第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

為什么我點(diǎn)按鈕好長(zhǎng)時(shí)間然后松開(kāi) 總是會(huì)出現(xiàn) 錄音時(shí)間過(guò)短的對(duì)話(huà)框,只要按了按鈕。不管時(shí)間長(zhǎng)短。最后總會(huì)出現(xiàn)這個(gè)錄音時(shí)間過(guò)短的這個(gè)對(duì)話(huà)框??茨曨l看了好幾次代碼也沒(méi)錯(cuò)。

public class AudioRecorderButton extends Button implements AudioStateListener {


private static final ?int DISTANCE_YCANCEL=50;

/**

* 默認(rèn)狀態(tài)

*/

private static final int ?STATE_NORMAL=1; ? ?//默認(rèn)狀態(tài)

/**

* 錄音狀態(tài)

*/

private static final int ?STATE_RECORDING=2; ? ? ? ? //錄音狀態(tài)

/**

* 取消狀態(tài)

*/

private static final int ?STATE_WANT_TO_CANCEL=3; ? ?//取消狀態(tài)

/**

* 當(dāng)前記錄狀態(tài)

*/

private int mCurState =STATE_NORMAL; //當(dāng)前記錄狀態(tài)

/**

* 已經(jīng)開(kāi)始錄音

*/

private boolean isRecording=false;

//調(diào)用AudioManager類(lèi)。錄音

private AudioManager mAudioManager;

//調(diào)用DialogManager類(lèi)。框

private DialogManager mDialogManager;

private float mTime;

//是否觸發(fā)longclcik

private boolean mReady;

public AudioRecorderButton(Context context) {

this(context,null);

}

public AudioRecorderButton(Context context, AttributeSet attrs) {

super(context, attrs);

//初始化DialogManager

mDialogManager=new DialogManager(getContext());

setOnLongClickListener(new OnLongClickListener() {

@Override

public boolean onLongClick(View arg0) {

mReady=true;

mAudioManager.prpareAudio();

return false;

}

});

//

String dir=Environment.getExternalStorageDirectory()+"/imooc_recorder_audios";

//初始化AudioManager

mAudioManager=AudioManager.getInstance(dir);

//調(diào)用回調(diào)接口

mAudioManager.setOnAudioStateListener(this);

}

private AudioFinishRecorderListener mListener;

/**

* 定義一個(gè)接口方法,讓外部可以set調(diào)用

* @param mListener

*/

public void setAudioFinishRecorderListener(AudioFinishRecorderListener mListener)

{

this.mListener=mListener;

}

/**

* 錄音完成后的回調(diào) 接口

* @author Administrator

*

*/

public interface AudioFinishRecorderListener

{

/**

* 1.錄音的時(shí)常

* 2.文件。地址

* @param seconds

* @param filePath

*/

public void onFinish(float seconds,String filePath);

}

/**

* 獲取音量大小的Runnable

*/

private Runnable mGetVoiceLevelRunnable=new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

while(isRecording)

{

try {

Thread.sleep(100);

mHandler.sendEmptyMessage(MSG_VOICE_CHANGED_);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

};

/**

* 準(zhǔn)備完全了

*/

private static final int MSG_AUDIO_PREPARED=0X110;

//

private static final int MSG_VOICE_CHANGED_=0X111;

//

private static final int MSG_DIALOG_DIMISS=0X112;

private Handler mHandler=new Handler()

{

public void handleMessage(android.os.Message msg)

{

switch (msg.what) {

case MSG_AUDIO_PREPARED:

//顯示回調(diào)以后、

mDialogManager.showRecordingDialog();

isRecording=true;

new Thread(mGetVoiceLevelRunnable).start();

break;

case MSG_VOICE_CHANGED_:

? ?mDialogManager.updateVoiceLevel(mAudioManager.getVoiceLevel(7));

break;

case MSG_DIALOG_DIMISS:

break;

}

};

};

/**

* AudioManager實(shí)現(xiàn)回調(diào)接口方法

*/

@Override

public void wellPrepared() {

// TODO Auto-generated method stub

mHandler.sendEmptyMessage(MSG_AUDIO_PREPARED);

}


/**

* 滑動(dòng)屏幕事件。

*/

@Override

public boolean onTouchEvent(MotionEvent event) {

int action =event.getAction();

int x=(int) event.getX();

int y =(int) event.getY();

switch (action) {

//按下

case MotionEvent.ACTION_DOWN:

? ? ? ? ? ? changeState(STATE_RECORDING);

break;

//移動(dòng)

case MotionEvent.ACTION_MOVE:

if(isRecording)

{

//根據(jù)x y的坐標(biāo),判斷是否取消

? ? ? ? ? ?if(wantToCancel(x,y))

? ? ? ? ? ?{

? ? ? ? ? ? changeState(STATE_WANT_TO_CANCEL);

? ? ? ? ? ?}else {

? ? ? ? ? ? changeState(STATE_RECORDING);

}

}

break;

? //松開(kāi)

? ?/*

? ? ? ? ?* 五種情況 1、down以后還沒(méi)觸發(fā)longclick 2、down以后觸發(fā)longClick還沒(méi)有prepaer完畢就松開(kāi)了

? ? ? ? ?* 3、錄音時(shí)間很短,沒(méi)有達(dá)到我們?cè)O(shè)定的值 4、 5、

? ? ? ? ?*/

case MotionEvent.ACTION_UP:

//判斷狀態(tài)。是否觸發(fā)longclick

//如果連ongclick也沒(méi)觸發(fā)就直接什么都不做,改變一下btooon的狀態(tài)

if(!mReady)

{

reset();

return super.onTouchEvent(event);

}

//就是說(shuō)啟動(dòng),但沒(méi)有啟動(dòng)完成

if(!isRecording || mTime < 0.5f)?

{

//顯示一個(gè)錄音太短的對(duì)話(huà)框

mDialogManager.tooShort();

mAudioManager.cancel();

//1秒后關(guān)閉dialog 延遲

mHandler.sendEmptyMessageDelayed(MSG_DIALOG_DIMISS, 1000);

}

//根據(jù)當(dāng)前狀態(tài)==正在錄音。

else if(mCurState == ?STATE_RECORDING) //正常錄音結(jié)束

? ? ? ? ? ? ? {

? ? ? ? ? ? ?mDialogManager.dimissDialog();

? ? ? ? ? ? ?//釋放資源

? ? ? ? ? ? ?mAudioManager.release();

? ? ? ? ? ? //調(diào)用回調(diào)錄音完成后的接口

? ? ? ? ? ? ?if(mListener !=null)

? ? ? ? ? ? {

? ? ? ? ? ? mListener.onFinish(mTime,mAudioManager.getCurrentFilePath());

? ? ? ? ? ? }

? ? ? ? ? ? ?//release

? ? ? ? ? ? ?//callbackToAct

? ? ? ? ? ? ? }else if(mCurState == STATE_WANT_TO_CANCEL)

? ? ? ? ? ? ? {

//cancel

? ? ? ? ? ? ?mDialogManager.dimissDialog();

? ? ? ? ? ? ?mAudioManager.cancel();

?}

? ? ? ? ? ? ? reset();

break;

}

return super.onTouchEvent(event);

}

/**

* 按下?tīng)顟B(tài)方法

* @param stateRecording

*/

private void changeState(int state) {

if(mCurState != state)

{

mCurState=state;

switch (state) {

case STATE_NORMAL:

? ? ? ? ? ? ? ? ?setBackgroundResource(R.drawable.btn_nomal);

? ? ? ? ? ? ? ? ?setText(R.string.str_normal);

break;

case STATE_RECORDING:

setBackgroundResource(R.drawable.btn_recording);

? ? ? ? ? ? ? ? ?setText(R.string.str_recording);

? ? ? ? ? ? ? ? ?if(isRecording)

? ? ? ? ? ? ? ? ?{

? ? ? ? ? ? ? ? //更新Dialog.recording();

? ? ? ? ? ? ? ? mDialogManager.recording();

? ? ? ? ? ? ? ? ?}

break;

case STATE_WANT_TO_CANCEL:

setBackgroundResource(R.drawable.btn_recording);

? ? ? ? ? ? ? ? ?setText(R.string.str_want_cancel);

? ? ? ? ? ? ? ? ?mDialogManager.wanToCancel();?

break;

}

}

}

/**

* 移動(dòng)狀態(tài)方法

* @param x

* @param y

* @return

*/

private boolean wantToCancel(int x, int y) {

// x<0 代碼橫坐標(biāo)已經(jīng)超出按鈕的以外,或者 ?x>getWidth()說(shuō)明到達(dá)按鈕的右部

//判斷手指已經(jīng)離開(kāi)按鈕

if(x<0 || x>getWidth())

{

return true;

}

//判斷手指的橫坐標(biāo)是否超出按鈕范圍

//如果y是在按鈕的上部或者下部超過(guò)的定義的這個(gè)DISTANCE_YCANCEL范圍

if(y < -DISTANCE_YCANCEL || y > getHeight()+DISTANCE_YCANCEL)

{

return true;

}

return false;

}

/**

* 恢復(fù)狀態(tài)及標(biāo)志位

*/

private void reset() {

? ? ?isRecording=false;

? ? ?mReady=false;

? ? ?mTime=0;

? ? ?changeState(STATE_NORMAL);

}



public class AudioManager {


/**

* 它用來(lái)記錄音頻和視頻,記錄控制基于一個(gè)簡(jiǎn)單的狀態(tài)機(jī)

*/

private MediaRecorder mMediaRecorder;

/**

* 文件夾的名稱(chēng) 因?yàn)橐浀囊旁谖募A里面

*/

private String mDir;

/**

* 因?yàn)楸4嫱暌貍鞯絙nttion

*/

private String mCurrentFilePath;

/**

* 標(biāo)記已經(jīng)state

*/

private boolean isPrepared;

/**

* 單例

*/

private static AudioManager mInstance;

/**

* 接口變量

*/

private ?AudioStateListener mListener;

/**

* 接口,

* 回調(diào)已經(jīng)完畢?

* @author Administrator

*

*/

public interface AudioStateListener

{

void wellPrepared();

}

public void setOnAudioStateListener(AudioStateListener Listener)

{

mListener=Listener;

}


//構(gòu)造方法

private AudioManager(String dir){

mDir=dir;

}

public static AudioManager getInstance(String dir)

{

if(mInstance == null)

{

//同步

synchronized (AudioManager.class) {

if(mInstance == null)

{

mInstance=new AudioManager(dir);

}

}

}

return mInstance;

}

/**

* 準(zhǔn)備

*/

public void prpareAudio()

{

try {

isPrepared=false;

File dir=new File(mDir);

if( !dir.exists())

dir.mkdirs();

String fileName=generateFileName();

File file=new File(dir, fileName);

//賦值

mCurrentFilePath=file.getAbsolutePath();

mMediaRecorder=new MediaRecorder();

//設(shè)置輸出文件

mMediaRecorder.setOutputFile(file.getAbsolutePath());

//設(shè)置MediaRecorder的音頻源為麥克風(fēng)

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

//設(shè)置音頻的格式

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);

//設(shè)置音頻的編碼為

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

mMediaRecorder.prepare();

mMediaRecorder.start();

//準(zhǔn)備結(jié)束

isPrepared=true;

//通知bntton

if(mListener != null)

{

mListener.wellPrepared();

}

} catch (IllegalStateException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

/**

* 隨即生成文件的名稱(chēng)

* @return

*/

private String generateFileName() {

return UUID.randomUUID().toString()+"amr";

}


/**

* 獲取當(dāng)前的一個(gè)音量的等級(jí)

* @param maxLevel

* @return

*/

public int getVoiceLevel(int maxLevel)

{

if(isPrepared)

{

try {

//mMediaRecorder.getMaxAmplitude()返回的是 1到32767

// mMediaRecorder.getMaxAmplitude()這個(gè)值的范圍 1-32767

//maxLevel最大為7

//得到的值在/32768 返回的0到1之間的小數(shù)。 然后再*maxLevel,在返回最小是0最大為6

//然后再加1的話(huà),就1到7

return maxLevel * mMediaRecorder.getMaxAmplitude()/32768+1;

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

return 1;

}

/**

* 釋放資源

*/

public void release()

{

mMediaRecorder.stop();

mMediaRecorder.release();

mMediaRecorder=null;

}

/**

* 取消

*/

public void cancel()

{

release();

if(mCurrentFilePath !=null)

{

File file=new File(mCurrentFilePath);

file.delete();

mCurrentFilePath=null;

}

}


/**

*?

* @return

*/

public String getCurrentFilePath() {

return mCurrentFilePath;

}



public class DialogManager {


private Dialog mDialog;


private ImageView mIcon;

private ImageView mVvoice;

private TextView mLable;

private Context mContext;


public DialogManager(Context context) {

mContext = context;

}


/**

* 顯示第一個(gè)對(duì)話(huà)框。也是默認(rèn)的樣子

* 顯示錄音的對(duì)話(huà)框

*/

public void showRecordingDialog()

{

mDialog =new Dialog(mContext, R.style.Theme_AudioDialog);

LayoutInflater inflater=LayoutInflater.from(mContext);

View view= inflater.inflate(R.layout.dialog_recorder, null);

mDialog.setContentView(view);

mIcon=(ImageView) mDialog.findViewById(R.id.id_recorder_dialog_icon);

mVvoice=(ImageView) mDialog.findViewById(R.id.id_recorder_dialog_voice);

mLable=(TextView) mDialog.findViewById(R.id.id_recoder_dilog_lable);

mDialog.show();

}

/**

*?

*/

public void recording()

{

if(mDialog!=null && mDialog.isShowing())

{

mIcon.setVisibility(View.VISIBLE);

mVvoice.setVisibility(View.VISIBLE);

mLable .setVisibility(View.VISIBLE);

mIcon.setImageResource(R.drawable.recorder);

mLable.setText("手指上滑,取消發(fā)送");

}

}

/**

* ?顯示wanToCancel的對(duì)話(huà)框

*/

public void wanToCancel()

{

if(mDialog!=null && mDialog.isShowing())

{

mIcon.setVisibility(View.VISIBLE);

mVvoice.setVisibility(View.GONE);

mLable .setVisibility(View.VISIBLE);

mIcon.setImageResource(R.drawable.cancel);

mLable.setText("松開(kāi)手指,取消發(fā)送");

}

}

/**

* 顯示tooShort的對(duì)話(huà)框

*/

public void tooShort()

{


if(mDialog!=null && mDialog.isShowing())

{

mIcon.setVisibility(View.VISIBLE);

mVvoice.setVisibility(View.GONE);

mLable .setVisibility(View.VISIBLE);

mIcon.setImageResource(R.drawable.voice_to_short);

mLable.setText("錄音時(shí)間過(guò)短");

}

}

/**

* 隱藏對(duì)話(huà)框

*/

public void dimissDialog()

{

if(mDialog!=null && mDialog.isShowing())

{

mDialog.dismiss();

mDialog=null;

}

}

/**

* 通過(guò)level去更新voice上的圖片

* 更新對(duì)話(huà)框里面的音量的一個(gè)標(biāo)志

* @param level

*/

public void updateVoiceLevel(int level)

{

if(mDialog!=null && mDialog.isShowing())

{

// mIcon.setVisibility(View.VISIBLE);

// mVvoice.setVisibility(View.VISIBLE);

// mLable .setVisibility(View.VISIBLE);

/**

* 通過(guò)方法名找到資源

*/

int resId=mContext.getResources().getIdentifier("v"+level, "drawable", mContext.getPackageName());

mVvoice.setImageResource(resId);

}

}

}


正在回答

3 回答

我也遇到了這個(gè)問(wèn)題 是因?yàn)閏hangeState函數(shù)中當(dāng)case為STATE_RECORDING時(shí)isRecording沒(méi)有設(shè)置為true,所以u(píng)p的時(shí)候調(diào)用了tooshort函數(shù)

0 回復(fù) 有任何疑惑可以回復(fù)我~

請(qǐng)問(wèn)你們解決了嗎這個(gè)問(wèn)題?我的也是,求指教,是獲得不到權(quán)限嗎?

0 回復(fù) 有任何疑惑可以回復(fù)我~

我也遇到了同樣的問(wèn)題 ?請(qǐng)問(wèn)你解決了嗎 ?是如何解決的

0 回復(fù) 有任何疑惑可以回復(fù)我~
#1

慕粉1005463403

請(qǐng)問(wèn)你們解決了嗎這個(gè)問(wèn)題?我的也是,求指教,是獲得不到權(quán)限嗎?
2016-12-30 回復(fù) 有任何疑惑可以回復(fù)我~

舉報(bào)

0/150
提交
取消
Android-仿微信語(yǔ)音聊天
  • 參與學(xué)習(xí)       43186    人
  • 解答問(wèn)題       248    個(gè)

結(jié)合自定義View和API,Dialog管理等實(shí)現(xiàn)實(shí)現(xiàn)微信語(yǔ)音

進(jìn)入課程

為什么我點(diǎn)按鈕好長(zhǎng)時(shí)間然后松開(kāi) 總是會(huì)出現(xiàn) 錄音時(shí)間過(guò)短的對(duì)話(huà)框,只要按了按鈕。不管時(shí)間長(zhǎng)短。最后總會(huì)出現(xiàn)這個(gè)錄音時(shí)間過(guò)短的這個(gè)對(duì)話(huà)框。看您視頻看了好幾次代碼也沒(méi)錯(cuò)。

我要回答 關(guān)注問(wèn)題
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)