`
104zz
  • 浏览: 1508377 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

android 仿微信聊天界面,以及语音录制功能

阅读更多

 

本例为模仿微信聊天界面UI设计,文字发送以及语言录制UI。

1先看效果图:




 

 

 

第一:chat.xml设计

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/chat_bg_default" >

    <!-- 标题栏 -->
    <RelativeLayout
        android:id="@+id/rl_layout"
        android:layout_width="fill_parent"
        android:layout_height="45dp"
        android:background="@drawable/title_bar"
        android:gravity="center_vertical" >

        <Button
            android:id="@+id/btn_back"
            android:layout_width="70dp"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:background="@drawable/title_btn_back"
            android:onClick="chat_back"
            android:text="返回"
            android:textColor="#fff"
            android:textSize="14sp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="白富美"
            android:textColor="#ffffff"
            android:textSize="20sp" />

        <ImageButton
            android:id="@+id/right_btn"
            android:layout_width="67dp"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp"
            android:background="@drawable/title_btn_right"
            android:src="@drawable/mm_title_btn_contact_normal" />
    </RelativeLayout>

    <!-- 底部按钮以及 编辑框 -->
    <RelativeLayout
        android:id="@+id/rl_bottom"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@drawable/chat_footer_bg" >

        <ImageView
            android:id="@+id/ivPopUp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dip"
            android:src="@drawable/chatting_setmode_msg_btn" />

        <RelativeLayout
            android:id="@+id/btn_bottom"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/ivPopUp" >

            <Button
                android:id="@+id/btn_send"
                android:layout_width="60dp"
                android:layout_height="40dp"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="10dp"
                android:background="@drawable/chat_send_btn"
                android:text="发送" />

            <EditText
                android:id="@+id/et_sendmessage"
                android:layout_width="fill_parent"
                android:layout_height="40dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:layout_toLeftOf="@id/btn_send"
                android:background="@drawable/login_edit_normal"
                android:singleLine="true"
                android:textSize="18sp" />
        </RelativeLayout>

        <TextView
            android:id="@+id/btn_rcd"
            android:layout_width="fill_parent"
            android:layout_height="40dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_toRightOf="@+id/ivPopUp"
            android:background="@drawable/chat_send_btn"
            android:gravity="center"
            android:text="按住说话"
            android:visibility="gone" />
    </RelativeLayout>
    
    <!-- 聊天内容 listview -->
    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@id/rl_bottom"
        android:layout_below="@id/rl_layout"
        android:cacheColorHint="#0000"
        android:divider="@null"
        android:dividerHeight="5dp"
        android:scrollbarStyle="outsideOverlay"
        android:stackFromBottom="true" />
    
    <!-- 录音显示UI层 -->
    <LinearLayout
        android:id="@+id/rcChat_popup"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:visibility="gone" >

        <include
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            layout="@layout/voice_rcd_hint_window" />
    </LinearLayout>

</RelativeLayout>
 

 

第二:语音录制类封装SoundMeter.java

package com.example.voice_rcd;

import java.io.IOException;

import android.media.MediaRecorder;
import android.os.Environment;

public  class SoundMeter {
	static final private double EMA_FILTER = 0.6;

	private MediaRecorder mRecorder = null;
	private double mEMA = 0.0;

	public void start(String name) {
		if (!Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED)) {
			return;
		}
		if (mRecorder == null) {
			mRecorder = new MediaRecorder();
			mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
			mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
			mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
			mRecorder.setOutputFile(android.os.Environment.getExternalStorageDirectory()+"/"+name);
			try {
				mRecorder.prepare();
				mRecorder.start();
				
				mEMA = 0.0;
			} catch (IllegalStateException e) {
				System.out.print(e.getMessage());
			} catch (IOException e) {
				System.out.print(e.getMessage());
			}

		}
	}

	public void stop() {
		if (mRecorder != null) {
			mRecorder.stop();
			mRecorder.release();
			mRecorder = null;
		}
	}

	public void pause() {
		if (mRecorder != null) {
			mRecorder.stop();
		}
	}

	public void start() {
		if (mRecorder != null) {
			mRecorder.start();
		}
	}

	public double getAmplitude() {
		if (mRecorder != null)
			return (mRecorder.getMaxAmplitude() / 2700.0);
		else
			return 0;

	}

	public double getAmplitudeEMA() {
		double amp = getAmplitude();
		mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
		return mEMA;
	}
}

 第三:主界面Activity源码,没写太多解释,相对比较简单的自己研究下:

package com.example.voice_rcd;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {
	/** Called when the activity is first created. */

	private Button mBtnSend;
	private TextView mBtnRcd;
	private Button mBtnBack;
	private EditText mEditTextContent;
	private RelativeLayout mBottom;
	private ListView mListView;
	private ChatMsgViewAdapter mAdapter;
	private List<ChatMsgEntity> mDataArrays = new ArrayList<ChatMsgEntity>();
	private boolean isShosrt = false;
	private LinearLayout voice_rcd_hint_loading, voice_rcd_hint_rcding,
			voice_rcd_hint_tooshort;
	private ImageView img1, sc_img1;
	private SoundMeter mSensor;
	private View rcChat_popup;
	private LinearLayout del_re;
	private ImageView chatting_mode_btn, volume;
	private boolean btn_vocie = false;
	private int flag = 1;
	private Handler mHandler = new Handler();
	private String voiceName;
	private long startVoiceT, endVoiceT;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.chat);
		// 启动activity时不自动弹出软键盘
		getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
		initView();

		initData();
	}

	public void initView() {
		mListView = (ListView) findViewById(R.id.listview);
		mBtnSend = (Button) findViewById(R.id.btn_send);
		mBtnRcd = (TextView) findViewById(R.id.btn_rcd);
		mBtnSend.setOnClickListener(this);
		mBtnBack = (Button) findViewById(R.id.btn_back);
		mBottom = (RelativeLayout) findViewById(R.id.btn_bottom);
		mBtnBack.setOnClickListener(this);
		chatting_mode_btn = (ImageView) this.findViewById(R.id.ivPopUp);
		volume = (ImageView) this.findViewById(R.id.volume);
		rcChat_popup = this.findViewById(R.id.rcChat_popup);
		img1 = (ImageView) this.findViewById(R.id.img1);
		sc_img1 = (ImageView) this.findViewById(R.id.sc_img1);
		del_re = (LinearLayout) this.findViewById(R.id.del_re);
		voice_rcd_hint_rcding = (LinearLayout) this
				.findViewById(R.id.voice_rcd_hint_rcding);
		voice_rcd_hint_loading = (LinearLayout) this
				.findViewById(R.id.voice_rcd_hint_loading);
		voice_rcd_hint_tooshort = (LinearLayout) this
				.findViewById(R.id.voice_rcd_hint_tooshort);
		mSensor = new SoundMeter();
		mEditTextContent = (EditText) findViewById(R.id.et_sendmessage);
		
		//语音文字切换按钮
		chatting_mode_btn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {

				if (btn_vocie) {
					mBtnRcd.setVisibility(View.GONE);
					mBottom.setVisibility(View.VISIBLE);
					btn_vocie = false;
					chatting_mode_btn
							.setImageResource(R.drawable.chatting_setmode_msg_btn);

				} else {
					mBtnRcd.setVisibility(View.VISIBLE);
					mBottom.setVisibility(View.GONE);
					chatting_mode_btn
							.setImageResource(R.drawable.chatting_setmode_voice_btn);
					btn_vocie = true;
				}
			}
		});
		mBtnRcd.setOnTouchListener(new OnTouchListener() {
			
			public boolean onTouch(View v, MotionEvent event) {
				//按下语音录制按钮时返回false执行父类OnTouch
				return false;
			}
		});
	}

	private String[] msgArray = new String[] { "有人就有恩怨","有恩怨就有江湖","人就是江湖","你怎么退出? ","生命中充满了巧合","两条平行线也会有相交的一天。"};

	private String[] dataArray = new String[] { "2012-10-31 18:00",
			"2012-10-31 18:10", "2012-10-31 18:11", "2012-10-31 18:20",
			"2012-10-31 18:30", "2012-10-31 18:35"};
	private final static int COUNT = 6;

	public void initData() {
		for (int i = 0; i < COUNT; i++) {
			ChatMsgEntity entity = new ChatMsgEntity();
			entity.setDate(dataArray[i]);
			if (i % 2 == 0) {
				entity.setName("白富美");
				entity.setMsgType(true);
			} else {
				entity.setName("高富帅");
				entity.setMsgType(false);
			}

			entity.setText(msgArray[i]);
			mDataArrays.add(entity);
		}

		mAdapter = new ChatMsgViewAdapter(this, mDataArrays);
		mListView.setAdapter(mAdapter);

	}

	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn_send:
			send();
			break;
		case R.id.btn_back:
			finish();
			break;
		}
	}

	private void send() {
		String contString = mEditTextContent.getText().toString();
		if (contString.length() > 0) {
			ChatMsgEntity entity = new ChatMsgEntity();
			entity.setDate(getDate());
			entity.setName("高富帅");
			entity.setMsgType(false);
			entity.setText(contString);

			mDataArrays.add(entity);
			mAdapter.notifyDataSetChanged();

			mEditTextContent.setText("");

			mListView.setSelection(mListView.getCount() - 1);
		}
	}

	private String getDate() {
		Calendar c = Calendar.getInstance();

		String year = String.valueOf(c.get(Calendar.YEAR));
		String month = String.valueOf(c.get(Calendar.MONTH));
		String day = String.valueOf(c.get(Calendar.DAY_OF_MONTH) + 1);
		String hour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));
		String mins = String.valueOf(c.get(Calendar.MINUTE));

		StringBuffer sbBuffer = new StringBuffer();
		sbBuffer.append(year + "-" + month + "-" + day + " " + hour + ":"
				+ mins);

		return sbBuffer.toString();
	}

	//按下语音录制按钮时
	@Override
	public boolean onTouchEvent(MotionEvent event) {

		if (!Environment.getExternalStorageDirectory().exists()) {
			Toast.makeText(this, "No SDCard", Toast.LENGTH_LONG).show();
			return false;
		}

		if (btn_vocie) {
			System.out.println("1");
			int[] location = new int[2];
			mBtnRcd.getLocationInWindow(location); // 获取在当前窗口内的绝对坐标
			int btn_rc_Y = location[1];
			int btn_rc_X = location[0];
			int[] del_location = new int[2];
			del_re.getLocationInWindow(del_location);
			int del_Y = del_location[1];
			int del_x = del_location[0];
			if (event.getAction() == MotionEvent.ACTION_DOWN && flag == 1) {
				if (!Environment.getExternalStorageDirectory().exists()) {
					Toast.makeText(this, "No SDCard", Toast.LENGTH_LONG).show();
					return false;
				}
				System.out.println("2");
				if (event.getY() > btn_rc_Y && event.getX() > btn_rc_X) {//判断手势按下的位置是否是语音录制按钮的范围内
					System.out.println("3");
					mBtnRcd.setBackgroundResource(R.drawable.voice_rcd_btn_pressed);
					rcChat_popup.setVisibility(View.VISIBLE);
					voice_rcd_hint_loading.setVisibility(View.VISIBLE);
					voice_rcd_hint_rcding.setVisibility(View.GONE);
					voice_rcd_hint_tooshort.setVisibility(View.GONE);
					mHandler.postDelayed(new Runnable() {
						public void run() {
							if (!isShosrt) {
								voice_rcd_hint_loading.setVisibility(View.GONE);
								voice_rcd_hint_rcding
										.setVisibility(View.VISIBLE);
							}
						}
					}, 300);
					img1.setVisibility(View.VISIBLE);
					del_re.setVisibility(View.GONE);
					startVoiceT = SystemClock.currentThreadTimeMillis();
					voiceName = startVoiceT + ".amr";
					start(voiceName);
					flag = 2;
				}
			} else if (event.getAction() == MotionEvent.ACTION_UP && flag == 2) {//松开手势时执行录制完成
				System.out.println("4");
				mBtnRcd.setBackgroundResource(R.drawable.voice_rcd_btn_nor);
				if (event.getY() >= del_Y
						&& event.getY() <= del_Y + del_re.getHeight()
						&& event.getX() >= del_x
						&& event.getX() <= del_x + del_re.getWidth()) {
					rcChat_popup.setVisibility(View.GONE);
					img1.setVisibility(View.VISIBLE);
					del_re.setVisibility(View.GONE);
					stop();
					flag = 1;
					File file = new File(android.os.Environment.getExternalStorageDirectory()+"/"
									+ voiceName);
					if (file.exists()) {
						file.delete();
					}
				} else {

					voice_rcd_hint_rcding.setVisibility(View.GONE);
					stop();
					endVoiceT = SystemClock.currentThreadTimeMillis();
					flag = 1;
					int time = (int) ((endVoiceT - startVoiceT) / 1000);
					if (time < 1) {
						isShosrt = true;
						voice_rcd_hint_loading.setVisibility(View.GONE);
						voice_rcd_hint_rcding.setVisibility(View.GONE);
						voice_rcd_hint_tooshort.setVisibility(View.VISIBLE);
						mHandler.postDelayed(new Runnable() {
							public void run() {
								voice_rcd_hint_tooshort
										.setVisibility(View.GONE);
								rcChat_popup.setVisibility(View.GONE);
								isShosrt = false;
							}
						}, 500);
						return false;
					}
					ChatMsgEntity entity = new ChatMsgEntity();
					entity.setDate(getDate());
					entity.setName("高富帅");
					entity.setMsgType(false);
					entity.setTime(time+"\"");
					entity.setText(voiceName);
					mDataArrays.add(entity);
					mAdapter.notifyDataSetChanged();
					mListView.setSelection(mListView.getCount() - 1);
					rcChat_popup.setVisibility(View.GONE);

				}
			}
			if (event.getY() < btn_rc_Y) {//手势按下的位置不在语音录制按钮的范围内
				System.out.println("5");
				Animation mLitteAnimation = AnimationUtils.loadAnimation(this,
						R.anim.cancel_rc);
				Animation mBigAnimation = AnimationUtils.loadAnimation(this,
						R.anim.cancel_rc2);
				img1.setVisibility(View.GONE);
				del_re.setVisibility(View.VISIBLE);
				del_re.setBackgroundResource(R.drawable.voice_rcd_cancel_bg);
				if (event.getY() >= del_Y
						&& event.getY() <= del_Y + del_re.getHeight()
						&& event.getX() >= del_x
						&& event.getX() <= del_x + del_re.getWidth()) {
					del_re.setBackgroundResource(R.drawable.voice_rcd_cancel_bg_focused);
					sc_img1.startAnimation(mLitteAnimation);
					sc_img1.startAnimation(mBigAnimation);
				}
			} else {

				img1.setVisibility(View.VISIBLE);
				del_re.setVisibility(View.GONE);
				del_re.setBackgroundResource(0);
			}
		}
		return super.onTouchEvent(event);
	}

	private static final int POLL_INTERVAL = 300;

	private Runnable mSleepTask = new Runnable() {
		public void run() {
			stop();
		}
	};
	private Runnable mPollTask = new Runnable() {
		public void run() {
			double amp = mSensor.getAmplitude();
			updateDisplay(amp);
			mHandler.postDelayed(mPollTask, POLL_INTERVAL);

		}
	};

	private void start(String name) {
		mSensor.start(name);
		mHandler.postDelayed(mPollTask, POLL_INTERVAL);
	}

	private void stop() {
		mHandler.removeCallbacks(mSleepTask);
		mHandler.removeCallbacks(mPollTask);
		mSensor.stop();
		volume.setImageResource(R.drawable.amp1);
	}

	private void updateDisplay(double signalEMA) {
		
		switch ((int) signalEMA) {
		case 0:
		case 1:
			volume.setImageResource(R.drawable.amp1);
			break;
		case 2:
		case 3:
			volume.setImageResource(R.drawable.amp2);
			
			break;
		case 4:
		case 5:
			volume.setImageResource(R.drawable.amp3);
			break;
		case 6:
		case 7:
			volume.setImageResource(R.drawable.amp4);
			break;
		case 8:
		case 9:
			volume.setImageResource(R.drawable.amp5);
			break;
		case 10:
		case 11:
			volume.setImageResource(R.drawable.amp6);
			break;
		default:
			volume.setImageResource(R.drawable.amp7);
			break;
		}
	}

	public void head_xiaohei(View v) { // 标题栏 返回按钮

	}
}

 第四:自定义的显示适配器:

package com.example.voice_rcd;

import java.util.List;

import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ChatMsgViewAdapter extends BaseAdapter {

	public static interface IMsgViewType {
		int IMVT_COM_MSG = 0;
		int IMVT_TO_MSG = 1;
	}

	private static final String TAG = ChatMsgViewAdapter.class.getSimpleName();

	private List<ChatMsgEntity> coll;

	private Context ctx;

	private LayoutInflater mInflater;
	private MediaPlayer mMediaPlayer = new MediaPlayer();

	public ChatMsgViewAdapter(Context context, List<ChatMsgEntity> coll) {
		ctx = context;
		this.coll = coll;
		mInflater = LayoutInflater.from(context);
	}

	public int getCount() {
		return coll.size();
	}

	public Object getItem(int position) {
		return coll.get(position);
	}

	public long getItemId(int position) {
		return position;
	}

	public int getItemViewType(int position) {
		// TODO Auto-generated method stub
		ChatMsgEntity entity = coll.get(position);

		if (entity.getMsgType()) {
			return IMsgViewType.IMVT_COM_MSG;
		} else {
			return IMsgViewType.IMVT_TO_MSG;
		}

	}

	public int getViewTypeCount() {
		// TODO Auto-generated method stub
		return 2;
	}

	public View getView(int position, View convertView, ViewGroup parent) {

		final ChatMsgEntity entity = coll.get(position);
		boolean isComMsg = entity.getMsgType();

		ViewHolder viewHolder = null;
		if (convertView == null) {
			if (isComMsg) {
				convertView = mInflater.inflate(
						R.layout.chatting_item_msg_text_left, null);
			} else {
				convertView = mInflater.inflate(
						R.layout.chatting_item_msg_text_right, null);
			}

			viewHolder = new ViewHolder();
			viewHolder.tvSendTime = (TextView) convertView
					.findViewById(R.id.tv_sendtime);
			viewHolder.tvUserName = (TextView) convertView
					.findViewById(R.id.tv_username);
			viewHolder.tvContent = (TextView) convertView
					.findViewById(R.id.tv_chatcontent);
			viewHolder.tvTime = (TextView) convertView
					.findViewById(R.id.tv_time);
			viewHolder.isComMsg = isComMsg;

			convertView.setTag(viewHolder);
		} else {
			viewHolder = (ViewHolder) convertView.getTag();
		}

		viewHolder.tvSendTime.setText(entity.getDate());
		
		if (entity.getText().contains(".amr")) {
			viewHolder.tvContent.setText("");
			viewHolder.tvContent.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.chatto_voice_playing, 0);
			viewHolder.tvTime.setText(entity.getTime());
		} else {
			viewHolder.tvContent.setText(entity.getText());			
			viewHolder.tvContent.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
			viewHolder.tvTime.setText("");
		}
		viewHolder.tvContent.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				if (entity.getText().contains(".amr")) {
					playMusic(android.os.Environment.getExternalStorageDirectory()+"/"+entity.getText()) ;
				}
			}
		});
		viewHolder.tvUserName.setText(entity.getName());
		
		return convertView;
	}

	static class ViewHolder {
		public TextView tvSendTime;
		public TextView tvUserName;
		public TextView tvContent;
		public TextView tvTime;
		public boolean isComMsg = true;
	}

	/**
	 * @Description
	 * @param name
	 */
	private void playMusic(String name) {
		try {
			if (mMediaPlayer.isPlaying()) {
				mMediaPlayer.stop();
			}
			mMediaPlayer.reset();
			mMediaPlayer.setDataSource(name);
			mMediaPlayer.prepare();
			mMediaPlayer.start();
			mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
				public void onCompletion(MediaPlayer mp) {

				}
			});

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void stop() {

	}

}
 

附上代码,希望有需要的可以下载研究完善。

  • 大小: 214.4 KB
  • 大小: 213.7 KB
  • 大小: 214.7 KB
  • 大小: 218 KB
  • 大小: 217.1 KB
分享到:
评论
53 楼 tvvbbb 2016-08-10  
辛苦楼主了
52 楼 希望花开的声音 2016-04-28  
都很好  就是这个获取时间的有问题。   SystemClock.currentThreadTimeMillis(); 换成 System.currentTimeMillis(); 录音就好了
  
51 楼 y331271939 2016-01-21  
看评论后说录音时间太短的自己动动脑就就行了,看看sdcard录制成功了,说明int time = (int) ((endVoiceT - startVoiceT) / 1000);这句代码有问题,改改就行了
50 楼 codeMoe 2015-11-24  
MediaRecorder prepare   CallingPid =  1102  Callinguid=  10286
at android.media.MediaRecorder.prepare(MediaRecorder.java:792)
at com.example.voice_rcd.SoundMeter.start(SoundMeter.java:26)
录音报了这个错误,请问博主这是什么原因?
49 楼 lc7183627 2015-10-22  
这个无法实现 音量长度不同 发送的语音信息长度不同 在onTouch里面不停的获取最新时间所以一直会提示音量太短。
48 楼 hwh199103 2015-10-11  
声音无法播放问题:private MediaPlayer mMediaPlayer = new MediaPlayer();改为private static MediaPlayer mMediaPlayer = new MediaPlayer();即可
47 楼 pkcfl 2015-09-02  
的确,改成System.currentTimeMillis()计时正确了
46 楼 pkcfl 2015-09-02  
博主做得不错!就冲这个界面就把些微瑕疵掩盖了
45 楼 巴士uncle 2015-08-07  
            
44 楼 cheng521314 2015-07-30  
可以点个赞吗?
43 楼 wdz99 2015-07-21  
不错,还能语音!!!
42 楼 xingzhiyu163 2015-07-07  
请问楼主有服务端吗 ?
41 楼 xiaomayi201314 2015-06-24  
楼主很强大 受用了
40 楼 333sunshine 2015-06-12  
   
39 楼 liang_yu2012 2015-01-30  
喵小皓 写道
int time = (int) ((endVoiceT - startVoiceT) / 1000); 这个计算说话长度不准确。稍微调整一下就不会提示时间太短了


弱弱的问一下
这块怎么修改?
38 楼 Mybeautiful 2015-01-22  
hackervip 写道
Mybeautiful 写道
播放声音时喇叭不懂,不过图片资源已经在里面了,稍微改下就好了。谢谢博主!


你好,哥们能说下怎么实现播放语音的喇叭动画吗,谢谢了我是个新手

就是监听语音的变化,换图片,看起来像在动一样。
37 楼 hackervip 2015-01-21  
Mybeautiful 写道
播放声音时喇叭不懂,不过图片资源已经在里面了,稍微改下就好了。谢谢博主!


你好,哥们能说下怎么实现播放语音的喇叭动画吗,谢谢了我是个新手
36 楼 Mybeautiful 2015-01-07  
播放声音时喇叭不懂,不过图片资源已经在里面了,稍微改下就好了。谢谢博主!
35 楼 Mybeautiful 2015-01-06  
下载看了下不错;不过里面有个图片 title_bar.9.png有点问题,导入android stuido提示这个不是.9格式的文件
34 楼 cspows 2015-01-03  
厉害厉害,学习了楼主谢谢了

相关推荐

    Android 仿微信聊天界面

    在Android开发中,仿微信聊天界面是一个常见的需求,它涉及到许多关键技术和组件的集成。这个项目可能包括消息列表的展示、输入框设计、表情键盘、发送按钮、未读消息提示等多个方面。以下是一些相关的重要知识点: ...

    android高仿微信聊天界面,语音,表情,拍照及本地图片选择功能

    在Android平台上,构建一个类似微信的聊天界面是一个常见的需求,涉及到多个关键技术点。这个项目,"HRChatDemo",显然就是一个实现这一目标的示例应用。让我们深入探讨一下其中涉及的关键技术及其细节。 首先,...

    Android--仿微信聊天界面

    在Android平台上,构建一个仿微信聊天界面涉及到...通过以上技术的组合和优化,可以实现一个功能完备、用户体验良好的Android仿微信聊天界面。在实际开发过程中,还需要不断调试和测试,确保各个功能的稳定性和流畅性。

    Android 仿微信语音录音小控件

    在Android开发中,有时我们需要创建类似微信的用户体验,其中就包括了语音录制功能。这个"Android仿微信语音录音小控件"就是一个实现此类功能的示例。它旨在为用户提供一个直观、简洁的录音界面,与微信应用中的语音...

    安卓仿微信语音聊天功能

    在安卓平台上实现类似微信的语音聊天功能,是一个常见的需求,涉及到多媒体处理、用户界面设计以及数据存储等多个技术领域。下面将详细阐述这个过程中的关键知识点。 1. **录音API**: 安卓系统提供了AudioRecord...

    Android仿微信语音聊天界面设计

    在本文中,我们将探讨如何在Android平台上实现一个...以上就是Android仿微信语音聊天界面设计的关键知识点和实现流程。通过这个设计,我们可以创建一个功能完备的语音消息系统,让用户能够方便地发送和接收语音消息。

    用Android studio写仿微信语音聊天功能

    在Android开发中,实现一个仿微信的语音聊天功能是一项具有挑战性的任务,涉及到多个技术模块的集成和优化。本文将详细解析如何使用Android Studio来构建这样的功能。 首先,我们需要了解语音录制与播放的基础。...

    Android-录制语音和播放语音仿微信语音模块

    在Android平台上,开发语音录制和播放功能是许多应用程序的核心需求,比如社交应用中的语音消息功能。本项目"Android-录制语音和播放语音仿微信语音模块"提供了一个轻量级的解决方案,它借鉴了环信(Easemob)的设计...

    Android---仿微信语音聊天

    综上所述,实现"Android---仿微信语音聊天"功能需要掌握Android的音频录制与播放API,网络编程,用户交互设计,以及权限管理等多个方面的知识。通过这些技术的综合运用,我们才能创建出一个功能完善的语音聊天应用。

    android仿微信语音录音demo

    在Android平台上,开发一款仿微信语音录音功能的Demo涉及到多个技术点,主要涵盖音频录制、文件操作、用户交互以及可能的音频格式处理等。以下是对这些关键知识点的详细阐述: 一、音频录制 1. MediaRecorder:...

    android仿微信聊天界面 语音录制功能

    总之,通过上述步骤,你可以创建一个具备语音录制功能的Android聊天界面,模仿微信的交互方式。注意,实际开发中可能还需要处理更多细节,如界面的自适应布局、性能优化等。对于初学者,这是一个很好的学习实践项目...

    android仿微信demo

    7. **多媒体处理**:如语音录制和播放、视频的上传和播放等功能,可能需要利用MediaRecorder、MediaPlayer等Android自带的多媒体API。 8. **权限管理**:随着Android系统对权限管理的加强,学习如何适配不同版本的...

    仿微信聊天实现

    在IT行业中,仿微信聊天的实现是一个常见的项目挑战,它涉及到多方面的技术,包括网络通信、数据存储、用户界面设计以及消息同步等。基于鸿洋大神的讲课内容,我们可以深入探讨这个话题。 首先,我们要理解微信聊天...

    Android开发--仿微信语音对讲录音,按住讲话进行录音,向上滑动可以进行取消录音.zip

    在Android开发中,实现“仿微信语音对讲录音”功能是一项常见的需求,它涉及到音频录制、用户交互以及事件处理等多个方面。在这个项目中,我们将会探讨如何构建这样一个系统,让用户可以按住按钮讲话进行录音,并...

    android仿微信聊天语音,表情,拍照及本地选择相册和本地保存聊天记录

    总结,实现“android仿微信聊天语音,表情,拍照及本地选择相册和本地保存聊天记录”涉及多个Android核心功能,包括多媒体处理、数据库操作、用户界面设计等。开发者需要具备扎实的Android基础知识,熟悉相关API的...

    仿微信android语音录制demo

    本教程将详细讲解如何构建一个带有精美界面的仿微信Android语音录制Demo,涵盖的主要知识点包括: 1. **麦克风权限**:在Android 6.0(API级别23)及以上版本,需要在运行时请求`RECORD_AUDIO`权限。确保在`...

    高仿微信聊天界面

    【标题】"高仿微信聊天界面"涉及到的是在Android平台上创建一个类似微信的聊天界面的实践项目。在Android开发中,构建这样的用户界面是提升用户体验的关键步骤,它要求开发者对UI设计、数据处理以及交互逻辑有深入...

Global site tag (gtag.js) - Google Analytics