您的位置:首页 > 移动开发 > 微信开发

Android 仿微信语音识别

2016-05-23 16:45 666 查看
参考与:http://www.2cto.com/kf/201505/396842.html,这网站代码跑起来有问题,自己改动了一下,基本上没什么大问题

发现问题可以评论,我会回复的

先贴下效果图







1、三个布局文件

activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.weixin_record.MainActivity" >

<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ebebeb"
android:divider="@null"
android:dividerHeight="10dp" >
</ListView>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<!-- minHeight消除主界面上的一些间距 -->

<com.nickming.view.AudioRecordButton
android:id="@+id/recordButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="7dp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:layout_marginTop="6dp"
android:background="@drawable/button_recordnormal"
android:gravity="center"
android:minHeight="0dp"
android:padding="5dp"
android:text="@string/normal"
android:textColor="#727272" >
</com.nickming.view.AudioRecordButton>

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ccc" />
</FrameLayout>

</LinearLayout>


dialog_manger.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/dialog_loading_bg"
android:gravity="center"
android:orientation="vertical"
android:padding="20dp"
tools:context="com.example.weixin_record.MainActivity" >

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<ImageView
android:id="@+id/dialog_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/recorder"
android:visibility="visible" />

<ImageView
android:id="@+id/dialog_voice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/v1"
android:visibility="visible" />
</LinearLayout>

<TextView
android:id="@+id/recorder_dialogtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="@string/shouzhishanghua"
android:textColor="#ffffffff" />

</LinearLayout>


item_layout
<?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="60dp"
android:layout_marginTop="5dp" >

<ImageView
android:id="@+id/item_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:src="@drawable/icon" />

<FrameLayout
android:id="@+id/recorder_length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/item_icon"
android:background="@drawable/chatto_bg_focused" >

<View
android:id="@+id/show_anim01"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="center_vertical|right"
android:background="@drawable/adj"/>

</FrameLayout>

<TextView
android:id="@+id/recorder_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="3dp"
android:layout_toLeftOf="@id/recorder_length"
android:text=""
android:textColor="#ff777777"/>

</RelativeLayout>


2.自定义的类
(1)DialogManger
package com.nickming.view;

import com.example.weixin_record.R;

import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
*
* @ClassName:  DialogManager
* @Description:对话框管理类
* @author:  张  维
* @date:   2016-5-23 下午4:56:03
*
*/
public class DialogManager {

/**
* 以下为dialog的初始化控件,包括其中的布局文件
*/

private Dialog mDialog;

private ImageView mIcon;
private ImageView mVoice;

private TextView mLable;

private Context mContext;

public DialogManager(Context context) {
mContext = context;
}

public void showRecordingDialog() {

mDialog = new Dialog(mContext,R.style.Theme_audioDialog);
// 用layoutinflater来引用布局
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.dialog_manager, null);
mDialog.setContentView(view);

mIcon = (ImageView) mDialog.findViewById(R.id.dialog_icon);
mVoice = (ImageView) mDialog.findViewById(R.id.dialog_voice);
mVoice.setBackgroundResource(R.drawable.play02);
AnimationDrawable drawable = (AnimationDrawable) mVoice
.getBackground();
drawable.start();
mLable = (TextView) mDialog.findViewById(R.id.recorder_dialogtext);
mDialog.show();

}

/**
* 设置正在录音时的dialog界面
*/
public void recording() {
if (mDialog != null && mDialog.isShowing()) {
mIcon.setVisibility(View.VISIBLE);
mVoice.setVisibility(View.VISIBLE);
mLable.setVisibility(View.VISIBLE);

mIcon.setImageResource(R.drawable.recorder);
mLable.setText(R.string.shouzhishanghua);
}
}

/**
* 取消界面
*/
public void wantToCancel() {
// TODO Auto-generated method stub
if (mDialog != null && mDialog.isShowing()) {
mIcon.setVisibility(View.VISIBLE);
mVoice.setVisibility(View.GONE);
mLable.setVisibility(View.VISIBLE);

mIcon.setImageResource(R.drawable.cancel);
mLable.setText(R.string.want_to_cancle);
}

}

// 时间过短
public void timeShort() {
// TODO Auto-generated method stub
if (mDialog != null && mDialog.isShowing()) {
mIcon.setVisibility(View.VISIBLE);
mVoice.setVisibility(View.GONE);
mLable.setVisibility(View.VISIBLE);

mIcon.setImageResource(R.drawable.voice_to_short);
mLable.setText(R.string.timeshort);
}

}

// 隐藏dialog
public void dimissDialog() {
// TODO Auto-generated method stub

if (mDialog != null && mDialog.isShowing()) {
mDialog.dismiss();
mDialog = null;
}

}

public void updateVoiceLevel(int level) {
// TODO Auto-generated method stub

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

//先不改变它的默认状态
//			mIcon.setVisibility(View.VISIBLE);
//			mVoice.setVisibility(View.VISIBLE);
//			mLable.setVisibility(View.VISIBLE);

//通过level来找到图片的id,也可以用switch来寻址,但是代码可能会比较长
int resId = mContext.getResources().getIdentifier("v" + level,
"drawable", mContext.getPackageName());

mVoice.setImageResource(resId);
}

}

}
(2)AudioRecordButton
package com.nickming.view;

import com.example.weixin_record.R;
import com.example.weixin_record.R.string;
import com.nickming.view.AudioManager.AudioStageListener;

import android.R.bool;
import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
/**
*
* @ClassName:  AudioRecordButton
* @Description:自定义的button按钮
* @author:  张  维
* @date:   2016-5-23 下午2:13:20
*
*/
public class AudioRecordButton extends Button implements AudioStageListener {

private static final int STATE_NORMAL = 1;
private static final int STATE_RECORDING = 2;
private static final int STATE_WANT_TO_CANCEL = 3;

private static final int DISTANCE_Y_CANCEL = 50;

private int mCurrentState = STATE_NORMAL;
// 已经开始录音
private boolean isRecording = false;

private DialogManager mDialogManager;

private AudioManager mAudioManager;

private float mTime = 0;
// 是否触发了onlongclick,准备好了
private boolean mReady;

/**
* 先实现两个参数的构造方法,布局会默认引用这个构造方法,
* 用一个 构造参数的构造方法来引用这个方法 * @param context
*/

public AudioRecordButton(Context context) {
this(context, null);
// TODO Auto-generated constructor stub
}

public AudioRecordButton(Context context, AttributeSet attrs) {
super(context, attrs);

mDialogManager = new DialogManager(getContext());

// 这里没有判断储存卡是否存在,有空要判断
String dir = Environment.getExternalStorageDirectory()
+ "/temp";
mAudioManager = AudioManager.getInstance(dir);
mAudioManager.setOnAudioStageListener(this);

setOnLongClickListener(new OnLongClickListener() {

@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method
mReady = true;
mAudioManager.prepareAudio();
return false;
}
});

}

/**
* 录音完成后的回调,回调给activiy,可以获得mtime和文件的路径
* @author nickming
*
*/
public interface AudioFinishRecorderListener{
void onFinished(float mtime,String filePath);
}

private AudioFinishRecorderListener mListener;

public void setAudioFinishRecorderListener(AudioFinishRecorderListener listener)
{
mListener=listener;
}

// 获取音量大小的runnable
private Runnable mGetVoiceLevelRunnable = new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
while (isRecording) {
try {
Thread.sleep(100);
mTime += 0.1f;
mhandler.sendEmptyMessage(MSG_VOICE_CHANGE);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};

// 准备三个常量
private static final int MSG_AUDIO_PREPARED = 0X110;
private static final int MSG_VOICE_CHANGE = 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:
// 显示应该是在audio end prepare之后回调
mDialogManager.showRecordingDialog();
isRecording = true;
new Thread(mGetVoiceLevelRunnable).start();

// 需要开启一个线程来变换音量
break;
case MSG_VOICE_CHANGE:
mDialogManager.updateVoiceLevel(mAudioManager.getVoiceLevel(7));

break;
case MSG_DIALOG_DIMISS:

break;

}
};
};

// 在这里面发送一个handler的消息
@Override
public void wellPrepared() {
// TODO Auto-generated method stub
mhandler.sendEmptyMessage(MSG_AUDIO_PREPARED);
}

/**
* 直接复写这个监听函数
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();

switch (action) {

case MotionEvent.ACTION_DOWN://表示用户开始触摸.
changeState(STATE_RECORDING);
break;
case MotionEvent.ACTION_MOVE://表示用户在移动(手指或者其他)

if (isRecording) {

// 根据x,y来判断用户是否想要取消
if (wantToCancel(x, y)) {
changeState(STATE_WANT_TO_CANCEL);
} else {
changeState(STATE_RECORDING);
}

}

break;
case MotionEvent.ACTION_UP://表示用户抬起了手指
// 首先判断是否有触发onlongclick事件,没有的话直接返回reset
if (!mReady) {
reset();
return super.onTouchEvent(event);
}
// 如果按的时间太短,还没准备好或者时间录制太短,就离开了,则显示这个dialog
if (!isRecording || mTime < 0.6f) {
mDialogManager.timeShort();//取消对话框
mAudioManager.cancel();
mhandler.sendEmptyMessageDelayed(MSG_DIALOG_DIMISS, 1300);// 持续1.3s
} else if (mCurrentState == STATE_RECORDING) {//正常录制结束

mDialogManager.dimissDialog();

mAudioManager.release();// release释放一个mediarecorder

if (mListener!=null) {// 并且callbackActivity,保存录音

mListener.onFinished(mTime, mAudioManager.getCurrentFilePath());
}

} else if (mCurrentState == STATE_WANT_TO_CANCEL) {
// cancel
mAudioManager.cancel();
mDialogManager.dimissDialog();
}
reset();// 恢复标志位

break;

}

return super.onTouchEvent(event);
}

/**
* 回复标志位以及状态
*/
private void reset() {
// TODO Auto-generated method stub
isRecording = false;
changeState(STATE_NORMAL);
mReady = false;
mTime = 0;
}

private boolean wantToCancel(int x, int y) {
// 超过按钮的宽度
if (x < 0 || x > getWidth()) {// 判断是否在左边,右边,上边,下边
return true;
}
// 超过按钮的高度
if (y < -DISTANCE_Y_CANCEL || y > getHeight() + DISTANCE_Y_CANCEL) {
return true;
}

return false;
}

private void changeState(int state) {

if (mCurrentState != state) {
mCurrentState = state;
switch (mCurrentState) {
case STATE_NORMAL:
setBackgroundResource(R.drawable.button_recordnormal);
setText(R.string.normal);

break;
case STATE_RECORDING:
setBackgroundResource(R.drawable.button_recording);
setText(R.string.recording);
if (isRecording) {
mDialogManager.recording();
// 复写dialog.recording();
}
break;

case STATE_WANT_TO_CANCEL:
setBackgroundResource(R.drawable.button_recording);
setText(R.string.want_to_cancle);
// 取消
mDialogManager.wantToCancel();
break;

}
}

}

@Override
public boolean onPreDraw() {
return false;
}

}
(3)MediaRecorder
package com.nickming.view;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

import android.media.MediaRecorder;
/**
*
* @ClassName:  AudioManager
* @Description: 录音的管理类(准备工作)
* @author:  张  维
* @date:   2016-5-23 下午2:10:35
*
*/
public class AudioManager {

private MediaRecorder mRecorder;
private String mDirString;
private String mCurrentFilePath;

private boolean isPrepared;// 是否准备好了

/**
* 单例化的方法
*  1 先声明一个static 类型的变量a
*  2 在声明默认的构造函数
*  3 再用public synchronized static
*   类名 getInstance() { if(a==null) { a=new 类();} return a; } 或者用以下的方法
*/

/**
* 单例化这个类
*/
private static AudioManager mInstance;

private AudioManager(String dir) {
mDirString=dir;
}

public static AudioManager getInstance(String dir) {
if (mInstance == null) {
synchronized (AudioManager.class) {
if (mInstance == null) {
mInstance = new AudioManager(dir);

}
}
}
return mInstance;

}

/**
* 回调函数,准备完毕,准备好后,button才会开始显示录音框
*
* @author nickming
*
*/
public interface AudioStageListener {
void wellPrepared();
}

public AudioStageListener mListener;

public void setOnAudioStageListener(AudioStageListener listener) {
mListener = listener;
}

// 准备方法
public void prepareAudio() {
try {
// 一开始应该是false的
isPrepared = false;

File dir = new File(mDirString);
//判断对象file是否存在
if (!dir.exists()) {
//创建此抽象路径指定的目录,包括所有必须但不存在的父目录。(及可以创建多级目录,无论是否存在父目录)
dir.mkdirs();
}

String fileNameString = generalFileName();
File file = new File(dir, fileNameString);

mCurrentFilePath = file.getAbsolutePath();

mRecorder = new MediaRecorder();
// 设置输出文件
mRecorder.setOutputFile(file.getAbsolutePath());
// 设置meidaRecorder的音频源是麦克风
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 设置文件音频的输出格式为amr
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
// 设置音频的编码格式为amr
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

// 严格遵守google官方api给出的mediaRecorder的状态流程图
mRecorder.prepare();

mRecorder.start();
// 准备结束
isPrepared = true;
// 已经准备好了,可以录制了
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();
}

}

/**
* 随机生成文件的名称
*
* @return
*/
private String generalFileName() {

//UUID.randomUUID().toString()是javaJDK提供的一个自动生成主键的方法。
return UUID.randomUUID().toString() + ".amr";
}

// 获得声音的大小
public int getVoiceLevel(int maxLevel) {
// mRecorder.getMaxAmplitude()这个是音频的振幅范围,值域是1-32767
if (isPrepared) {
try {
// 取证+1,否则去不到7
return maxLevel * mRecorder.getMaxAmplitude() / 32768 + 1;
} catch (Exception e) {

}
}

return 1;
}

// 释放资源
public void release() {
// 严格按照api流程进行
mRecorder.stop();
mRecorder.release();
mRecorder = null;

}

// 取消,因为prepare时产生了一个文件,所以cancel方法应该要删除这个文件,
// 这是与release的方法的区别
public void cancel() {
release();
if (mCurrentFilePath != null) {
File file = new File(mCurrentFilePath);
file.delete();//删除文件
mCurrentFilePath = null;
}

}

public String getCurrentFilePath() {
return mCurrentFilePath;
}

}


3.调用的类
(1)RecorderAdapter
package com.example.weixin_record;

import java.util.List;

import com.example.weixin_record.MainActivity.Recorder;

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.TextView;
/**
*
* @ClassName:  RecorderAdapter
* @Description:list的适配器
* @author:  张  维
* @date:   2016-5-23 下午4:04:02
*
*/
public class RecorderAdapter extends ArrayAdapter<Recorder> {

private LayoutInflater inflater;

private int mMinItemWith;// 设置对话框的最大宽度和最小宽度
private int mMaxItemWith;

public RecorderAdapter(Context context, List<Recorder> dataList) {
super(context, -1, dataList);

inflater = LayoutInflater.from(context);

// 获取系统宽度
WindowManager wManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wManager.getDefaultDisplay().getMetrics(outMetrics);
mMaxItemWith = (int) (outMetrics.widthPixels * 0.7f);
mMinItemWith = (int) (outMetrics.widthPixels * 0.15f);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_layout, parent, false);

viewHolder=new ViewHolder();
viewHolder.seconds=(TextView) convertView.findViewById(R.id.recorder_time);
viewHolder.length=convertView.findViewById(R.id.recorder_length);

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

viewHolder.seconds.setText(Math.round(getItem(position).time)+"\"");
ViewGroup.LayoutParams lParams=viewHolder.length.getLayoutParams();
lParams.width=(int) (mMinItemWith+mMaxItemWith/60f*getItem(position).time);
viewHolder.length.setLayoutParams(lParams);

return convertView;
}

class ViewHolder {
TextView seconds;// 时间
View length;// 对话框长度
}

}


(2)MediaManager

package com.example.weixin_record;

import java.io.IOException;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.util.Log;
/**
*
* @ClassName:  MediaManager
* @Description:播放的管理类
* @author:  张  维
* @date:   2016-5-23 下午4:04:43
*
*/
public class MediaManager {

private static MediaPlayer mPlayer;

private static boolean isPause;

public static  void playSound(String filePathString,
OnCompletionListener onCompletionListener) {

if (mPlayer==null) {
mPlayer=new MediaPlayer();
//保险起见,设置报错监听
mPlayer.setOnErrorListener(new OnErrorListener() {

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i("info", "");
mPlayer.reset();
return false;
}
});
}else {
mPlayer.reset();//就回复
}

try {
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setOnCompletionListener(onCompletionListener);
mPlayer.setDataSource(filePathString);
mPlayer.prepare();
mPlayer.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

//停止函数
public static void pause(){
if (mPlayer!=null&&mPlayer.isPlaying()) {
mPlayer.pause();
isPause=true;
}
}

//继续
public static void resume()
{
if (mPlayer!=null&&isPause) {
mPlayer.start();
isPause=false;
}
}

public  static void release()
{
if (mPlayer!=null) {
mPlayer.release();
mPlayer=null;
}
}
}


(3)MainActivity
package com.example.weixin_record;

import java.util.ArrayList;
import java.util.List;

import com.nickming.view.AudioRecordButton;
import com.nickming.view.AudioRecordButton.AudioFinishRecorderListener;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
AudioRecordButton button;

private ListView mlistview;
private ArrayAdapter<Recorder> mAdapter;
private View viewanim;
private List<Recorder> mDatas = new ArrayList<MainActivity.Recorder>();

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

mlistview = (ListView) findViewById(R.id.listview);

button = (AudioRecordButton) findViewById(R.id.recordButton);
button.setAudioFinishRecorderListener(new AudioFinishRecorderListener() {

@Override
public void onFinished(float seconds, String filePath) {
// TODO Auto-generated method stub
Recorder recorder = new Recorder(seconds, filePath);
mDatas.add(recorder);
mAdapter.notifyDataSetChanged();
mlistview.setSelection(mDatas.size() - 1);
}
});

mAdapter = new RecorderAdapter(this, mDatas);
mlistview.setAdapter(mAdapter);

mlistview.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {

// 播放动画
if (viewanim!=null) {//让第二个播放的时候第一个停止播放
viewanim.setBackgroundResource(R.drawable.adj);
viewanim=null;
}
viewanim = view.findViewById(R.id.show_anim01);
viewanim.setBackgroundResource(R.drawable.play);
AnimationDrawable drawable = (AnimationDrawable) viewanim
.getBackground();
drawable.start();

// 播放音频
Log.i("info", "position==="+position);
MediaManager.playSound(mDatas.get(position).filePathString,
new MediaPlayer.OnCompletionListener() {

@Override
public void onCompletion(MediaPlayer mp) {
viewanim.setBackgroundResource(R.drawable.adj);

}
});
}
});
}

@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
MediaManager.pause();
}

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
MediaManager.resume();
}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
MediaManager.release();
}

class Recorder {
float time;
String filePathString;

public Recorder(float time, String filePathString) {
super();
this.time = time;
this.filePathString = filePathString;
}

public float getTime() {
return time;
}

public void setTime(float time) {
this.time = time;
}

public String getFilePathString() {
return filePathString;
}

public void setFilePathString(String filePathString) {
this.filePathString = filePathString;
}

}

}


要完整的Demo下载地址: http://download.csdn.net/detail/zhang106209/9528686
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: