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);
    			}
    		}
    	}
            

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

          






      

  • 相关阅读:
    docker容器的时间同步
    Java中的各种bean对应的意义(VO,PO,BO,QO, DAO,POJO,DTO)
    Vue-admin工作整理(十九):从数字渐变组件谈第三方JS库Count-to的使用
    HTTP 方法:Get与Post分析
    Java核心知识盘点(三)- 框架篇-Spring
    Java核心知识盘点(二)- 缓存使用
    Java核心知识盘点(一)- 数据存储
    Java基础知识盘点(三)- 线程篇
    Java基础知识盘点(二)- 集合篇
    Java基础知识盘点(一)- 基础篇
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6763701.html
Copyright © 2011-2022 走看看