在好例子网,分享、交流、成长!
您当前所在位置:首页Java 开发实例Android平台开发 → 高仿微信源码(凡信开源客户端代码)

高仿微信源码(凡信开源客户端代码)

Android平台开发

下载此实例
  • 开发语言:Java
  • 实例大小:17.16M
  • 下载次数:31
  • 浏览次数:1020
  • 发布时间:2015-11-25
  • 实例类别:Android平台开发
  • 发 布 人:tompeson
  • 文件格式:.zip
  • 所需积分:4
 相关标签: 凡信开源客户端代码 XMPP

实例介绍

【实例简介】Fanxin2.1.6_byXMPP11 有些只是实现了UI,并没有实现程序功能

【实例截图】

【核心代码】


/**
 * Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.fanxin.app.activity;

import java.text.SimpleDateFormat;
import java.util.UUID;

import android.content.Context;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.easemob.chat.EMCallStateChangeListener;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMMessage;
import com.easemob.chat.TextMessageBody;
import com.fanxin.app.Constant;
import com.fanxin.app.R;
import com.easemob.exceptions.EMServiceNotReadyException;

/**
 * 语音通话页面
 * 
 */
public class VoiceCallActivity extends BaseActivity implements OnClickListener {
	private LinearLayout comingBtnContainer;
	private Button hangupBtn;
	private Button refuseBtn;
	private Button answerBtn;
	private ImageView muteImage;
	private ImageView handsFreeImage;

	private boolean isMuteState;
	private boolean isHandsfreeState;
	private boolean isInComingCall;
	private TextView callStateTextView;
	private SoundPool soundPool;
	private int streamID;
	private boolean endCallTriggerByMe = false;
	private Handler handler = new Handler();
	private Ringtone ringtone;
	private int outgoing;
	private TextView nickTextView;
	private TextView durationTextView;
	private SimpleDateFormat dateFormat;
	private WindowManager windowManager;
	private AudioManager audioManager;
	private Chronometer chronometer;

	private String callDruationText;
	private String username;
	private CallingState callingState = CallingState.CANCED;
	String msgid;
	private boolean isAnswered;
	private LinearLayout voiceContronlLayout;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_voice_call);

		comingBtnContainer = (LinearLayout) findViewById(R.id.ll_coming_call);
		refuseBtn = (Button) findViewById(R.id.btn_refuse_call);
		answerBtn = (Button) findViewById(R.id.btn_answer_call);
		hangupBtn = (Button) findViewById(R.id.btn_hangup_call);
		muteImage = (ImageView) findViewById(R.id.iv_mute);
		handsFreeImage = (ImageView) findViewById(R.id.iv_handsfree);
		callStateTextView = (TextView) findViewById(R.id.tv_call_state);
		nickTextView = (TextView) findViewById(R.id.tv_nick);
		durationTextView = (TextView) findViewById(R.id.tv_calling_duration);
		chronometer = (Chronometer) findViewById(R.id.chronometer);
		voiceContronlLayout = (LinearLayout) findViewById(R.id.ll_voice_control);

		refuseBtn.setOnClickListener(this);
		answerBtn.setOnClickListener(this);
		hangupBtn.setOnClickListener(this);
		muteImage.setOnClickListener(this);
		handsFreeImage.setOnClickListener(this);

		getWindow().addFlags(
				WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
						| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
		audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
		audioManager.setMicrophoneMute(false);

		// 注册语音电话的状态的监听
		addCallStateListener();
		msgid = UUID.randomUUID().toString();

		username = getIntent().getStringExtra("username");
		// 语音电话是否为接收的
		isInComingCall = getIntent().getBooleanExtra("isComingCall", false);

		// 设置通话人
		nickTextView.setText(username);
		if (!isInComingCall) {// 拨打电话
			soundPool = new SoundPool(1, AudioManager.STREAM_RING, 0);
			outgoing = soundPool.load(this, R.raw.outgoing, 1);

			comingBtnContainer.setVisibility(View.INVISIBLE);
			hangupBtn.setVisibility(View.VISIBLE);
			callStateTextView.setText("正在呼叫...");
			handler.postDelayed(new Runnable() {
				public void run() {
					streamID = playMakeCallSounds();
				}
			}, 300);
			try {
				// 拨打语音电话
				EMChatManager.getInstance().makeVoiceCall(username);
			} catch (EMServiceNotReadyException e) {
				e.printStackTrace();
				runOnUiThread(new Runnable() {
					public void run() {
						Toast.makeText(VoiceCallActivity.this, "尚未连接至服务器", 0).show();
					}
				});
			}
		} else { // 有电话进来
			voiceContronlLayout.setVisibility(View.INVISIBLE);
			Uri ringUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
			audioManager.setMode(AudioManager.MODE_RINGTONE);
			audioManager.setSpeakerphoneOn(true);
			ringtone = RingtoneManager.getRingtone(this, ringUri);
			ringtone.play();
		}
	}

	/**
	 * 设置电话监听
	 */
	void addCallStateListener() {
		EMChatManager.getInstance().addVoiceCallStateChangeListener(new EMCallStateChangeListener() {

			@Override
			public void onCallStateChanged(CallState callState, CallError error) {
				// Message msg = handler.obtainMessage();
				switch (callState) {

				case CONNECTING: // 正在连接对方
					VoiceCallActivity.this.runOnUiThread(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							callStateTextView.setText("正在连接对方...");
						}

					});
					break;
				case CONNECTED: // 双方已经建立连接
					VoiceCallActivity.this.runOnUiThread(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							callStateTextView.setText("已经和对方建立连接,等待对方接受...");
						}

					});
					break;

				case ACCEPTED: // 电话接通成功
					VoiceCallActivity.this.runOnUiThread(new Runnable() {

						@Override
						public void run() {
							try {
								if (soundPool != null)
									soundPool.stop(streamID);
							} catch (Exception e) {
							}
							closeSpeakerOn();
							chronometer.setVisibility(View.VISIBLE);
							chronometer.setBase(SystemClock.elapsedRealtime());
							// 开始记时
							chronometer.start();
							callStateTextView.setText("通话中...");
							callingState = CallingState.NORMAL;
						}

					});
					break;
				case DISCONNNECTED: // 电话断了
					final CallError fError = error;
					VoiceCallActivity.this.runOnUiThread(new Runnable() {
						private void postDelayedCloseMsg() {
							handler.postDelayed(new Runnable() {

								@Override
								public void run() {
									saveCallRecord();
									Animation animation = new AlphaAnimation(1.0f, 0.0f);
									animation.setDuration(800);
									findViewById(R.id.root_layout).startAnimation(animation);
									finish();
								}

							}, 200);
						}

						@Override
						public void run() {
							chronometer.stop();
							callDruationText = chronometer.getText().toString();

							if (fError == CallError.REJECTED) {
								callingState = CallingState.BEREFUESD;
								callStateTextView.setText("对方拒绝接受!...");
							} else if (fError == CallError.ERROR_TRANSPORT) {
								callStateTextView.setText("连接建立失败!...");
							} else if (fError == CallError.ERROR_INAVAILABLE) {
								callingState = CallingState.OFFLINE;
								callStateTextView.setText("对方不在线,请稍后再拨...");
							} else if (fError == CallError.ERROR_BUSY) {
								callingState = CallingState.BUSY;
								callStateTextView.setText("对方正在通话中,请稍后再拨");
							} else if (fError == CallError.ERROR_NORESPONSE) {
								callingState = CallingState.NORESPONSE;
								callStateTextView.setText("对方未接听");
							} else {
								if (isAnswered) {
									callingState = CallingState.NORMAL;
									if (endCallTriggerByMe) {
										callStateTextView.setText("挂断...");
									} else {
										callStateTextView.setText("对方已经挂断...");
									}
								} else {
									if (isInComingCall) {
										callingState = CallingState.UNANSWERED;
										callStateTextView.setText("未接听");
									} else {
										callingState = CallingState.CANCED;
										callStateTextView.setText("已取消");
									}
								}
							}
							postDelayedCloseMsg();
						}

					});

					break;

				default:
					break;
				}

			}
		});
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_refuse_call: // 拒绝接听
			if (ringtone != null)
				ringtone.stop();
			try {
				EMChatManager.getInstance().rejectCall();
			} catch (Exception e1) {
				e1.printStackTrace();
				saveCallRecord();
				finish();
			}
			callingState = CallingState.REFUESD;
			break;

		case R.id.btn_answer_call: // 接听电话
			comingBtnContainer.setVisibility(View.INVISIBLE);
			hangupBtn.setVisibility(View.VISIBLE);
			voiceContronlLayout.setVisibility(View.VISIBLE);
			if (ringtone != null)
				ringtone.stop();
			closeSpeakerOn();
			if (isInComingCall) {
				try {
					isAnswered = true;
					EMChatManager.getInstance().answerCall();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					saveCallRecord();
					finish();
				}
			}
			break;

		case R.id.btn_hangup_call: // 挂断电话
			if (soundPool != null)
				soundPool.stop(streamID);
			endCallTriggerByMe = true;
			try {
				EMChatManager.getInstance().endCall();
			} catch (Exception e) {
				e.printStackTrace();
				saveCallRecord();
				finish();
			}
			break;

		case R.id.iv_mute: // 静音开关
			if (isMuteState) {
				// 关闭静音
				muteImage.setImageResource(R.drawable.icon_mute_normal);
				audioManager.setMicrophoneMute(false);
				isMuteState = false;
			} else {
				// 打开静音
				muteImage.setImageResource(R.drawable.icon_mute_on);
				audioManager.setMicrophoneMute(true);
				isMuteState = true;
			}
			break;
		case R.id.iv_handsfree: // 免提开关
			if (isHandsfreeState) {
				// 关闭免提
				handsFreeImage.setImageResource(R.drawable.icon_speaker_normal);
				closeSpeakerOn();
				isHandsfreeState = false;
			} else {
				handsFreeImage.setImageResource(R.drawable.icon_speaker_on);
				openSpeakerOn();
				isHandsfreeState = true;
			}
			break;
		default:
			break;
		}
	}

	/**
	 * 播放拨号响铃
	 * 
	 * @param sound
	 * @param number
	 */
	private int playMakeCallSounds() {
		try {
			// 最大音量
			float audioMaxVolumn = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
			// 当前音量
			float audioCurrentVolumn = audioManager.getStreamVolume(AudioManager.STREAM_RING);
			float volumnRatio = audioCurrentVolumn / audioMaxVolumn;

			audioManager.setMode(AudioManager.MODE_RINGTONE);
			audioManager.setSpeakerphoneOn(false);

			// 播放
			int id = soundPool.play(outgoing, // 声音资源
					volumnRatio, // 左声道
					volumnRatio, // 右声道
					1, // 优先级,0最低
					-1, // 循环次数,0是不循环,-1是永远循环
					1); // 回放速度,0.5-2.0之间。1为正常速度
			return id;
		} catch (Exception e) {
			return -1;
		}
	}

	@Override
	protected void onDestroy() {
		if (soundPool != null)
			soundPool.release();
		if (ringtone != null && ringtone.isPlaying())
			ringtone.stop();
		audioManager.setMode(AudioManager.MODE_NORMAL);
		super.onDestroy();
	}

	@Override
	public void onBackPressed() {
		EMChatManager.getInstance().endCall();
		callDruationText = chronometer.getText().toString();
		saveCallRecord();
		finish();
	}

	// 打开扬声器
	public void openSpeakerOn() {
		try {
//			audioManager.setMode(AudioManager.MODE_IN_CALL);
			AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

			if (!audioManager.isSpeakerphoneOn())
				audioManager.setSpeakerphoneOn(true);
			 audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
//			audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),
//					AudioManager.STREAM_VOICE_CALL);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 关闭扬声器
	public void closeSpeakerOn() {

		try {
			AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
			if (audioManager != null) {
//				int curVolume = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
				if (audioManager.isSpeakerphoneOn())
					audioManager.setSpeakerphoneOn(false);
				 audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
//				audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, curVolume, AudioManager.STREAM_VOICE_CALL);

			}

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

	/**
	 * 保存通话消息记录
	 */
	private void saveCallRecord() {
		EMMessage message = null;
		TextMessageBody txtBody = null;
		if (!isInComingCall) { // 打出去的通话
			message = EMMessage.createSendMessage(EMMessage.Type.TXT);
			message.setReceipt(username);
		} else {
			message = EMMessage.createReceiveMessage(EMMessage.Type.TXT);
			message.setFrom(username);
		}

		switch (callingState) {
		case NORMAL:
			txtBody = new TextMessageBody("通话时长 "   callDruationText);
			break;
		case REFUESD:
			txtBody = new TextMessageBody("已拒绝");
			break;
		case BEREFUESD:
			txtBody = new TextMessageBody("对方已拒绝");
			break;
		case OFFLINE:
			txtBody = new TextMessageBody("对方不在线");
			break;
		case BUSY:
			txtBody = new TextMessageBody("对方正在通话中");
			break;
		case NORESPONSE:
			txtBody = new TextMessageBody("对方未接听");
			break;
		case UNANSWERED:
			txtBody = new TextMessageBody("未接听");
			break;
		default:
			txtBody = new TextMessageBody("已取消");
			break;
		}
		// 设置扩展属性
		message.setAttribute(Constant.MESSAGE_ATTR_IS_VOICE_CALL, true);

		// 设置消息body
		message.addBody(txtBody);
		message.setMsgId(msgid);

		// 保存
		EMChatManager.getInstance().saveMessage(message, false);
	}

	enum CallingState {
		CANCED, NORMAL, REFUESD, BEREFUESD, UNANSWERED, OFFLINE, NORESPONSE, BUSY
	}
}


实例下载地址

高仿微信源码(凡信开源客户端代码)

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 javahand 发表于: 2015-11-26 16:13 17
很好的一个AmbilWarnaDialog

支持(0) 盖楼(回复)

第 2 楼 javahand 发表于: 2015-11-26 16:13 22
很好的一个AmbilWarnaDialog

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有2条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警