android项目 之 记事本(13) ----- 查看图片及播放录音
本文是自己学习所做笔记,欢迎转载。但请注明出处:http://blog.csdn.net/jesson20121020
今天就来实现下查看图片及录音的功能,在编辑或者浏览记事时,点击图片。打开一个自己定义Activity(当然了,也能够调用系统的图库来查看)来查看所加入的图片的原始图片。而不是缩放后的图片,同理,用自己定义Activity来查看录音文件。实现播放录音的功能。
上图:
从图中也能够看出,我们首先要创建两个Activity。当然了,布局文件也是少不了的。例如以下:
activity_show_picture.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/iv_showPic" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" /> </LinearLayout>ShowPicture.java
public class ShowPicture extends Activity { private ImageView img; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.activity_show_picture); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_add); //设置标题 TextView tv_title = (TextView)findViewById(R.id.tv_title); tv_title.setText("查看图片"); Button bt_back = (Button)findViewById(R.id.bt_back); bt_back.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { ShowPicture.this.finish(); } }); Button bt_del = (Button)findViewById(R.id.bt_save); bt_del.setBackgroundResource(R.drawable.paint_icon_delete); img = (ImageView)findViewById(R.id.iv_showPic); Intent intent = this.getIntent(); String imgPath = intent.getStringExtra("imgPath"); Bitmap bm = BitmapFactory.decodeFile(imgPath); img.setImageBitmap(bm); } }主要思想就是用ImageView来显示指定路径的图片。该路径是从前一个Activity中传入进来的。
这里的监听事件。仅仅实现了返回的功能,至于,放大缩小图片。旋转图片。下节再实现吧。activity_show_record.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" android:layout_centerInParent="true" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center" android:layout_margin="5dp" > <ImageView android:id="@+id/iv_record_wave_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dp" android:background="@anim/record_wave_left" /> <ImageView android:id="@+id/iv_microphone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/record_microphone_icon" android:layout_margin="5dp" /> <ImageView android:id="@+id/iv_record_wave_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dp" android:background="@anim/record_wave_right" /> </LinearLayout> <TextView android:id="@+id/tv_recordTime" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#499df7" android:textSize="20sp" android:text="00:00:00" android:gravity="center" android:layout_margin="5dp" /> </LinearLayout> </RelativeLayout>ShowRecord.java
public class ShowRecord extends Activity { private String audioPath; private int isPlaying = 0; private AnimationDrawable ad_left,ad_right; private Timer mTimer; //语音操作对象 private MediaPlayer mPlayer = null; private ImageView iv_record_wave_left,iv_record_wave_right,iv_microphone; private TextView tv_recordTime; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.activity_show_record); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_add); //设置标题 TextView tv_title = (TextView)findViewById(R.id.tv_title); tv_title.setText("查看录音"); Button bt_back = (Button)findViewById(R.id.bt_back); bt_back.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if(isPlaying == 1){ mPlayer.stop(); mPlayer.release(); } ShowRecord.this.finish(); } }); Button bt_del = (Button)findViewById(R.id.bt_save); bt_del.setBackgroundResource(R.drawable.paint_icon_delete); Intent intent = this.getIntent(); audioPath = intent.getStringExtra("audioPath"); iv_microphone = (ImageView)findViewById(R.id.iv_microphone); iv_microphone.setOnClickListener(new ClickEvent()); iv_record_wave_left = (ImageView)findViewById(R.id.iv_record_wave_left); iv_record_wave_right = (ImageView)findViewById(R.id.iv_record_wave_right); ad_left = (AnimationDrawable)iv_record_wave_left.getBackground(); //ad_left = (AnimationDrawable)iv_record_wave_left.getDrawable(); ad_right = (AnimationDrawable)iv_record_wave_right.getBackground(); //ad_right = (AnimationDrawable)iv_record_wave_right.getDrawable(); tv_recordTime = (TextView)findViewById(R.id.tv_recordTime); } final Handler handler = new Handler(){ public void handleMessage(Message msg) { switch(msg.what){ case 1 : String time[] = tv_recordTime.getText().toString().split(":"); int hour = Integer.parseInt(time[0]); int minute = Integer.parseInt(time[1]); int second = Integer.parseInt(time[2]); if(second < 59){ second++; } else if(second == 59 && minute < 59){ minute++; second = 0; } if(second == 59 && minute == 59 && hour < 98){ hour++; minute = 0; second = 0; } time[0] = hour + ""; time[1] = minute + ""; time[2] = second + ""; //调整格式显示到屏幕上 if(second < 10) time[2] = "0" + second; if(minute < 10) time[1] = "0" + minute; if(hour < 10) time[0] = "0" + hour; //显示在TextView中 tv_recordTime.setText(time[0]+":"+time[1]+":"+time[2]); break; } } }; class ClickEvent implements OnClickListener{ @Override public void onClick(View arg0) { // TODO Auto-generated method stub //试听 if(isPlaying == 0){ isPlaying = 1; mPlayer = new MediaPlayer(); tv_recordTime.setText("00:00:00"); mTimer = new Timer(); mPlayer.setOnCompletionListener(new MediaCompletion()); try { mPlayer.setDataSource(audioPath); mPlayer.prepare(); mPlayer.start(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } mTimer.schedule(new TimerTask() { @Override public void run() { Message message = new Message(); message.what = 1; handler.sendMessage(message); } }, 1000,1000); //播放动画 ad_left.start(); ad_right.start(); } //结束试听 else{ isPlaying = 0; mPlayer.stop(); mPlayer.release(); mPlayer = null; mTimer.cancel(); mTimer = null; //停止动画 ad_left.stop(); ad_right.stop(); } } } class MediaCompletion implements OnCompletionListener{ @Override public void onCompletion(MediaPlayer mp) { mTimer.cancel(); mTimer = null; isPlaying = 0; //停止动画 ad_left.stop(); ad_right.stop(); Toast.makeText(ShowRecord.this, "播放完成", Toast.LENGTH_SHORT).show(); tv_recordTime.setText("00:00:00"); } } }在查看录音时,用到了对播放时间的显示处理。以及动画的播放与停止,稍有点复杂,这些在之前“加入录音”一节就就讲述了。
有了这两个Activity后,那么剩下的工作就是在单击图片或者录音的事件中启动这两个Activity就可以。但这就有一个问题,怎样在图文混排的EditText中的推断单击的是图片。录音,还是文字呢??这就须要从EditText中的识别那些是图片。那些是文字,再进一步对图片分析究竟单击的是那一个图片,从而实现查看详细图片及录音的功能,详细例如以下:
1. 记录EditText中每一个图片的位置及所在源路径
为了实如今编辑和浏览时能够随时查看原图片及录音文件,所以在每次加入图片或录音后,用一个List记住新添加的每一个图片或录音的位置及所在路径,当然了,假设是浏览已经存在于数据库中的记事时。在载入数据的同一时候,相同用ListView来记住全部的图片及录音的位置和路径。
主要代码例如以下:
//记录editText中的图片。用于单击时推断单击的是那一个图片 private List<Map<String,String>> imgList = new ArrayList<Map<String,String>>();
每次单击记事列表项。进入查看记事。在载入数据的同一时候将全部图片及录音的位置及路径记录下来。详细为在loadDate()方法中加入下面代码:
//用List记录该录音的位置及所在路径。用于单击事件 Map<String,String> map = new HashMap<String,String>(); map.put("location", m.start()+"-"+m.end()); map.put("path", path); imgList.add(map);同理。也要在每次加入图片录音后也要加入对应的代码,在InsertBitmap()函数中加入例如以下代码:
//用List记录该录音的位置及所在路径。用于单击事件 Map<String,String> map = new HashMap<String,String>(); map.put("location", selectionIndex+"-"+(selectionIndex+spannableString.length())); map.put("path", imgPath); imgList.add(map);
2. 给EditText加入单击事件
private LineEditText et_Notes; ... ... et_Notes.setOnClickListener(new TextClickEvent());
3. 推断单击的是图片还是普通文字
为了推断单击的是图片还是普通文字,用到了Spanned,ImageSpan。主要思想,就是推断当前单击的位置是否在图片的位置范围内,主要代码例如以下:
Spanned s = et_Notes.getText(); ImageSpan[] imageSpans; imageSpans = s.getSpans(0, s.length(), ImageSpan.class); int selectionStart = et_Notes.getSelectionStart(); for(ImageSpan span : imageSpans){ int start = s.getSpanStart(span); int end = s.getSpanEnd(span); //找到图片 if(selectionStart >= start && selectionStart < end){ ... ... } }打到了图片,接下来就要推断单击的究竟是那一图片呢?
4. 决断单击的详细是那一张图片
这就用到了第一步记录的图片的位置和路径了,显然,就是用位置来推断究竟是单击的那一个图片。主要代码例如以下:
//查找当前单击的图片是哪一个图片 //System.out.println(start+"-----------"+end); String path = null; for(int i = 0;i < imgList.size();i++){ Map map = imgList.get(i); //找到了 if(map.get("location").equals(start+"-"+end)){ path = imgList.get(i).get("path"); break; } }
5. 推断是录音还是图片,启动相应的Activity,并传递路径
查看图片,有两种方法,一种是调用系统的图库打开图片,还有一种就是自己定义,这里。我都实现了。打开录音用的是自己定义的Activity,例如以下:
//接着推断当前图片是否是录音。假设为录音,则跳转到试听录音的Activity,假设不是,则跳转到查看图片的界面 //录音,则跳转到试听录音的Activity if(path.substring(path.length()-3, path.length()).equals("amr")){ Intent intent = new Intent(AddActivity.this,ShowRecord.class); intent.putExtra("audioPath", path); startActivity(intent); } //图片。则跳转到查看图片的界面 else{ //有两种方法,查看图片。第一种就是直接调用系统的图库查看图片。另外一种是自己定义Activity //调用系统图库查看图片 /*Intent intent = new Intent(Intent.ACTION_VIEW); File file = new File(path); Uri uri = Uri.fromFile(file); intent.setDataAndType(uri, "image/*");*/ //使用自己定义Activity Intent intent = new Intent(AddActivity.this,ShowPicture.class); intent.putExtra("imgPath", path); startActivity(intent); }以上。3,4,5步事实上都是在单击的监听器中实现的。完整代码例如以下:
//为EidtText设置监听器 class TextClickEvent implements OnClickListener{ @Override public void onClick(View v) { Spanned s = et_Notes.getText(); ImageSpan[] imageSpans; imageSpans = s.getSpans(0, s.length(), ImageSpan.class); int selectionStart = et_Notes.getSelectionStart(); for(ImageSpan span : imageSpans){ int start = s.getSpanStart(span); int end = s.getSpanEnd(span); //找到图片 if(selectionStart >= start && selectionStart < end){ //Bitmap bitmap = ((BitmapDrawable)span.getDrawable()).getBitmap(); //查找当前单击的图片是哪一个图片 //System.out.println(start+"-----------"+end); String path = null; for(int i = 0;i < imgList.size();i++){ Map map = imgList.get(i); //找到了 if(map.get("location").equals(start+"-"+end)){ path = imgList.get(i).get("path"); break; } } //接着推断当前图片是否是录音。假设为录音。则跳转到试听录音的Activity,假设不是,则跳转到查看图片的界面 //录音,则跳转到试听录音的Activity if(path.substring(path.length()-3, path.length()).equals("amr")){ Intent intent = new Intent(AddActivity.this,ShowRecord.class); intent.putExtra("audioPath", path); startActivity(intent); } //图片,则跳转到查看图片的界面 else{ //有两种方法,查看图片,第一种就是直接调用系统的图库查看图片,另外一种是自己定义Activity //调用系统图库查看图片 /*Intent intent = new Intent(Intent.ACTION_VIEW); File file = new File(path); Uri uri = Uri.fromFile(file); intent.setDataAndType(uri, "image/*");*/ //使用自己定义Activity Intent intent = new Intent(AddActivity.this,ShowPicture.class); intent.putExtra("imgPath", path); startActivity(intent); } } else //假设单击的是空白出或文字。则获得焦点,即打开软键盘 imm.showSoftInput(et_Notes, 0); } } }
至此。就实现了查看图片以及播放录音的功能。