zoukankan      html  css  js  c++  java
  • 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);
    			}
    		}
    	}
            

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

          






      

  • 相关阅读:
    一个简单XQuery查询的例子
    《Microsoft Sql server 2008 Internals》读书笔记第七章Special Storage(1)
    《Microsoft Sql server 2008 Internals》读书笔记第八章The Query Optimizer(4)
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(4)
    SQL Server中SMO备份数据库进度条不显示?
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(5)
    《Microsoft Sql server 2008 Internal》读书笔记第七章Special Storage(3)
    《Microsoft Sql server 2008 Internal》读书笔记第八章The Query Optimizer(2)
    省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例
    FireFox意外崩溃时的手工恢复命令
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6763701.html
Copyright © 2011-2022 走看看