├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── mariostudio │ │ └── audiorecoder │ │ ├── AudioListAdapter.java │ │ ├── AudioRecoderDialog.java │ │ ├── AudioRecoderUtils.java │ │ ├── BasePopupWindow.java │ │ ├── MainActivity.java │ │ └── ProgressTextUtils.java │ └── res │ ├── drawable │ ├── layer_recording_animation.xml │ ├── selector_recodering_btn.xml │ ├── shape_recoder_btn_normal.xml │ ├── shape_recoder_btn_recoding.xml │ └── shape_window_background.xml │ ├── layout │ ├── activity_main.xml │ ├── layout_list_item.xml │ └── layout_recoder_dialog.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── icon_microphone_normal.png │ └── icon_microphone_recoding.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | AudioRecoder -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Android 12 | 13 | 14 | Android > Lint > Correctness 15 | 16 | 17 | Java 18 | 19 | 20 | Java language level migration aidsJava 21 | 22 | 23 | 24 | 25 | Android 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.3" 6 | 7 | defaultConfig { 8 | applicationId "com.mariostudio.audiorecoder" 9 | minSdkVersion 14 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.2.0' 26 | compile 'com.android.support:design:23.2.0' 27 | } 28 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in E:\android-sdk_r24.3.2-windows/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/mariostudio/audiorecoder/AudioListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.mariostudio.audiorecoder; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | 9 | /** 10 | * Created by MarioStudio on 2016/5/12. 11 | */ 12 | public class AudioListAdapter extends BaseAdapter { 13 | 14 | private Context mContext; 15 | private LayoutInflater mInflater; 16 | 17 | public AudioListAdapter(Context context) { 18 | mInflater = LayoutInflater.from(context); 19 | this.mContext = context; 20 | } 21 | 22 | @Override 23 | public int getCount() { 24 | return 1; 25 | } 26 | 27 | @Override 28 | public Object getItem(int position) { 29 | return null; 30 | } 31 | 32 | @Override 33 | public long getItemId(int position) { 34 | return 0; 35 | } 36 | 37 | @Override 38 | public View getView(int position, View convertView, ViewGroup parent) { 39 | return mInflater.inflate(R.layout.layout_list_item, null); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/mariostudio/audiorecoder/AudioRecoderDialog.java: -------------------------------------------------------------------------------- 1 | package com.mariostudio.audiorecoder; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.widget.ImageView; 8 | import android.widget.TextView; 9 | 10 | /** 11 | * Created by MarioStudio on 2016/5/12. 12 | */ 13 | 14 | public class AudioRecoderDialog extends BasePopupWindow { 15 | 16 | private ImageView imageView; 17 | private TextView textView; 18 | 19 | public AudioRecoderDialog(Context context) { 20 | super(context); 21 | View contentView = LayoutInflater.from(context).inflate(R.layout.layout_recoder_dialog, null); 22 | imageView = (ImageView) contentView.findViewById(android.R.id.progress); 23 | textView = (TextView) contentView.findViewById(android.R.id.text1); 24 | setContentView(contentView); 25 | } 26 | 27 | public void setLevel(int level) { 28 | Drawable drawable = imageView.getDrawable(); 29 | drawable.setLevel(3000 + 6000 * level / 100); 30 | } 31 | 32 | public void setTime(long time) { 33 | textView.setText(ProgressTextUtils.getProgressText(time)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/mariostudio/audiorecoder/AudioRecoderUtils.java: -------------------------------------------------------------------------------- 1 | package com.mariostudio.audiorecoder; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import android.media.MediaRecorder; 7 | import android.os.Handler; 8 | import android.util.Log; 9 | 10 | /** 11 | * Created by MarioStudio on 2016/5/12. 12 | */ 13 | 14 | public class AudioRecoderUtils { 15 | 16 | private String filePath; 17 | private MediaRecorder mMediaRecorder; 18 | private final String TAG = "MediaRecord"; 19 | public static final int MAX_LENGTH = 1000 * 60 * 10;// 最大录音时长1000*60*10; 20 | 21 | private OnAudioStatusUpdateListener audioStatusUpdateListener; 22 | 23 | public AudioRecoderUtils(){ 24 | this.filePath = "/dev/null"; 25 | } 26 | 27 | public AudioRecoderUtils(File file) { 28 | this.filePath = file.getAbsolutePath(); 29 | } 30 | 31 | private long startTime; 32 | private long endTime; 33 | 34 | /** 35 | * 开始录音 使用amr格式 36 | * 录音文件 37 | * @return 38 | */ 39 | public void startRecord() { 40 | // 开始录音 41 | /* ①Initial:实例化MediaRecorder对象 */ 42 | if (mMediaRecorder == null) 43 | mMediaRecorder = new MediaRecorder(); 44 | try { 45 | /* ②setAudioSource/setVedioSource */ 46 | mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风 47 | /* ②设置音频文件的编码:AAC/AMR_NB/AMR_MB/Default 声音的(波形)的采样 */ 48 | mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); 49 | /* 50 | * ②设置输出文件的格式:THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式 51 | * ,H263视频/ARM音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要求为AMR_NB) 52 | */ 53 | mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 54 | /* ③准备 */ 55 | mMediaRecorder.setOutputFile(filePath); 56 | mMediaRecorder.setMaxDuration(MAX_LENGTH); 57 | mMediaRecorder.prepare(); 58 | /* ④开始 */ 59 | mMediaRecorder.start(); 60 | // AudioRecord audioRecord. 61 | /* 获取开始时间* */ 62 | startTime = System.currentTimeMillis(); 63 | updateMicStatus(); 64 | Log.i("ACTION_START", "startTime" + startTime); 65 | } catch (IllegalStateException e) { 66 | Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage()); 67 | } catch (IOException e) { 68 | Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage()); 69 | } 70 | } 71 | 72 | /** 73 | * 停止录音 74 | */ 75 | public long stopRecord() { 76 | if (mMediaRecorder == null) 77 | return 0L; 78 | endTime = System.currentTimeMillis(); 79 | Log.i("ACTION_END", "endTime" + endTime); 80 | mMediaRecorder.stop(); 81 | mMediaRecorder.reset(); 82 | mMediaRecorder.release(); 83 | mMediaRecorder = null; 84 | Log.i("ACTION_LENGTH", "Time" + (endTime - startTime)); 85 | return endTime - startTime; 86 | } 87 | 88 | private final Handler mHandler = new Handler(); 89 | 90 | private Runnable mUpdateMicStatusTimer = new Runnable() { 91 | public void run() { 92 | updateMicStatus(); 93 | } 94 | }; 95 | 96 | /** 97 | * 更新话筒状态 98 | */ 99 | private int BASE = 1; 100 | private int SPACE = 100;// 间隔取样时间 101 | 102 | public void setOnAudioStatusUpdateListener(OnAudioStatusUpdateListener audioStatusUpdateListener) { 103 | this.audioStatusUpdateListener = audioStatusUpdateListener; 104 | } 105 | 106 | private void updateMicStatus() { 107 | if (mMediaRecorder != null) { 108 | double ratio = (double)mMediaRecorder.getMaxAmplitude() / BASE; 109 | double db = 0;// 分贝 110 | if (ratio > 1) { 111 | db = 20 * Math.log10(ratio); 112 | if(null != audioStatusUpdateListener) { 113 | audioStatusUpdateListener.onUpdate(db); 114 | } 115 | } 116 | mHandler.postDelayed(mUpdateMicStatusTimer, SPACE); 117 | } 118 | } 119 | 120 | public interface OnAudioStatusUpdateListener { 121 | public void onUpdate(double db); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/src/main/java/com/mariostudio/audiorecoder/BasePopupWindow.java: -------------------------------------------------------------------------------- 1 | package com.mariostudio.audiorecoder; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.graphics.drawable.ColorDrawable; 7 | import android.graphics.drawable.Drawable; 8 | import android.view.KeyEvent; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.view.Window; 12 | import android.view.WindowManager; 13 | import android.widget.PopupWindow; 14 | 15 | /** 16 | * Created by MarioStudio on 2016/5/7. 17 | */ 18 | 19 | public class BasePopupWindow extends PopupWindow { 20 | 21 | private Context mContext; 22 | private float mShowAlpha = 0.88f; 23 | private Drawable mBackgroundDrawable; 24 | 25 | @Override 26 | public int getAnimationStyle() { 27 | return super.getAnimationStyle(); 28 | } 29 | 30 | public BasePopupWindow(Context context) { 31 | this.mContext = context; 32 | initBasePopupWindow(); 33 | } 34 | 35 | @Override 36 | public void setOutsideTouchable(boolean touchable) { 37 | super.setOutsideTouchable(touchable); 38 | if(touchable) { 39 | if(mBackgroundDrawable == null) { 40 | mBackgroundDrawable = new ColorDrawable(0x00000000); 41 | } 42 | super.setBackgroundDrawable(mBackgroundDrawable); 43 | } else { 44 | super.setBackgroundDrawable(null); 45 | } 46 | } 47 | 48 | @Override 49 | public void setBackgroundDrawable(Drawable background) { 50 | mBackgroundDrawable = background; 51 | setOutsideTouchable(isOutsideTouchable()); 52 | } 53 | 54 | /** 55 | * 初始化BasePopupWindow的一些信息 56 | * */ 57 | private void initBasePopupWindow() { 58 | setAnimationStyle(android.R.style.Animation_Dialog); 59 | setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); 60 | setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); 61 | setOutsideTouchable(false); //默认设置outside点击无响应 62 | setFocusable(true); 63 | } 64 | 65 | @Override 66 | public void setContentView(View contentView) { 67 | if(contentView != null) { 68 | contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); 69 | super.setContentView(contentView); 70 | addKeyListener(contentView); 71 | } 72 | } 73 | 74 | public Context getContext() { 75 | return mContext; 76 | } 77 | 78 | @Override 79 | public void showAtLocation(View parent, int gravity, int x, int y) { 80 | super.showAtLocation(parent, gravity, x, y); 81 | ValueAnimator animator = showAnimator(); 82 | if(animator != null) { 83 | animator.start(); 84 | } 85 | } 86 | 87 | @Override 88 | public void showAsDropDown(View anchor) { 89 | super.showAsDropDown(anchor); 90 | ValueAnimator animator = showAnimator(); 91 | if(animator != null) { 92 | animator.start(); 93 | } 94 | } 95 | 96 | @Override 97 | public void showAsDropDown(View anchor, int xoff, int yoff) { 98 | super.showAsDropDown(anchor, xoff, yoff); 99 | ValueAnimator animator = showAnimator(); 100 | if(animator != null) { 101 | animator.start(); 102 | } 103 | } 104 | 105 | @Override 106 | public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) { 107 | super.showAsDropDown(anchor, xoff, yoff, gravity); 108 | ValueAnimator animator = showAnimator(); 109 | if(animator != null) { 110 | animator.start(); 111 | } 112 | } 113 | 114 | @Override 115 | public void dismiss() { 116 | super.dismiss(); 117 | ValueAnimator animator = dismissAnimator(); 118 | if(animator != null) { 119 | animator.start(); 120 | } 121 | } 122 | 123 | public void setShowAlpha(float alpha) { 124 | this.mShowAlpha = alpha; 125 | } 126 | 127 | /** 128 | * 窗口显示,窗口背景透明度渐变动画 129 | * */ 130 | private ValueAnimator showAnimator() { 131 | if(mShowAlpha != 1.0f) { 132 | ValueAnimator animator = ValueAnimator.ofFloat(1.0f, mShowAlpha); 133 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 134 | 135 | @Override 136 | public void onAnimationUpdate(ValueAnimator animation) { 137 | float alpha = (float) animation.getAnimatedValue(); 138 | setWindowBackgroundAlpha(alpha); 139 | } 140 | }); 141 | animator.setDuration(360); 142 | return animator; 143 | } else { 144 | return null; 145 | } 146 | } 147 | 148 | /** 149 | * 窗口隐藏,窗口背景透明度渐变动画 150 | * */ 151 | private ValueAnimator dismissAnimator() { 152 | if(mShowAlpha != 1.0f) { 153 | ValueAnimator animator = ValueAnimator.ofFloat(mShowAlpha, 1.0f); 154 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 155 | 156 | @Override 157 | public void onAnimationUpdate(ValueAnimator animation) { 158 | float alpha = (float) animation.getAnimatedValue(); 159 | setWindowBackgroundAlpha(alpha); 160 | } 161 | }); 162 | animator.setDuration(320); 163 | return animator; 164 | } else { 165 | return null; 166 | } 167 | } 168 | 169 | /** 170 | * 为窗体添加outside点击事件 171 | * */ 172 | private void addKeyListener(View contentView) { 173 | if(contentView != null) { 174 | contentView.setFocusable(true); 175 | contentView.setFocusableInTouchMode(true); 176 | contentView.setOnKeyListener(new View.OnKeyListener() { 177 | 178 | @Override 179 | public boolean onKey(View view, int keyCode, KeyEvent event) { 180 | switch (keyCode) { 181 | case KeyEvent.KEYCODE_BACK: 182 | dismiss(); 183 | return true; 184 | default: 185 | break; 186 | } 187 | return false; 188 | } 189 | }); 190 | } 191 | } 192 | 193 | /** 194 | * 控制窗口背景的不透明度 195 | * */ 196 | private void setWindowBackgroundAlpha(float alpha) { 197 | Window window = ((Activity)getContext()).getWindow(); 198 | WindowManager.LayoutParams layoutParams = window.getAttributes(); 199 | layoutParams.alpha = alpha; 200 | window.setAttributes(layoutParams); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /app/src/main/java/com/mariostudio/audiorecoder/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.mariostudio.audiorecoder; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.os.Bundle; 6 | import android.os.Environment; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.view.Gravity; 9 | import android.view.MotionEvent; 10 | import android.view.View; 11 | import android.view.Window; 12 | import android.view.WindowManager; 13 | import android.widget.ListView; 14 | import android.widget.TextView; 15 | 16 | import java.io.File; 17 | 18 | public class MainActivity extends AppCompatActivity implements View.OnTouchListener, AudioRecoderUtils.OnAudioStatusUpdateListener { 19 | 20 | private AudioRecoderDialog recoderDialog; 21 | private AudioRecoderUtils recoderUtils; 22 | private ListView listView; 23 | private TextView button; 24 | private long downT; 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | setContentView(R.layout.activity_main); 30 | 31 | //判断SDK版本是否大于等于19,大于就让他显示,小于就要隐藏,不然低版本会多出来一个 32 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 33 | setTranslucentStatus(true); 34 | //还有设置View的高度,因为每个型号的手机状态栏高度都不相同 35 | } 36 | 37 | button = (TextView) findViewById(android.R.id.button1); 38 | button.setOnTouchListener(this); 39 | 40 | recoderDialog = new AudioRecoderDialog(this); 41 | recoderDialog.setShowAlpha(0.98f); 42 | 43 | recoderUtils = new AudioRecoderUtils(new File(Environment.getExternalStorageDirectory() + "/recoder.amr")); 44 | recoderUtils.setOnAudioStatusUpdateListener(this); 45 | // 46 | // listView = (ListView) findViewById(android.R.id.list); 47 | // listView.setAdapter(new AudioListAdapter(this)); 48 | } 49 | 50 | @TargetApi(19) 51 | private void setTranslucentStatus(boolean on) { 52 | Window win = getWindow(); 53 | WindowManager.LayoutParams winParams = win.getAttributes(); 54 | final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; 55 | if (on) { 56 | winParams.flags |= bits; 57 | } else { 58 | winParams.flags &= ~bits; 59 | } 60 | win.setAttributes(winParams); 61 | } 62 | 63 | @Override 64 | public boolean onTouch(View view, MotionEvent event) { 65 | switch(event.getAction()) { 66 | case MotionEvent.ACTION_DOWN: 67 | recoderUtils.startRecord(); 68 | downT = System.currentTimeMillis(); 69 | recoderDialog.showAtLocation(view, Gravity.CENTER, 0, 0); 70 | button.setBackgroundResource(R.drawable.shape_recoder_btn_recoding); 71 | return true; 72 | case MotionEvent.ACTION_UP: 73 | recoderUtils.stopRecord(); 74 | recoderDialog.dismiss(); 75 | button.setBackgroundResource(R.drawable.shape_recoder_btn_normal); 76 | return true; 77 | } 78 | return false; 79 | } 80 | 81 | @Override 82 | public void onUpdate(double db) { 83 | if(null != recoderDialog) { 84 | int level = (int) db; 85 | recoderDialog.setLevel((int)db); 86 | recoderDialog.setTime(System.currentTimeMillis() - downT); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/com/mariostudio/audiorecoder/ProgressTextUtils.java: -------------------------------------------------------------------------------- 1 | package com.mariostudio.audiorecoder; 2 | 3 | import java.text.DecimalFormat; 4 | import java.util.Calendar; 5 | import java.util.Date; 6 | 7 | /** 8 | * Created by MarioStudio on 2016/3/13. 9 | */ 10 | 11 | public class ProgressTextUtils { 12 | 13 | public static String getProgressText(long time) { 14 | Calendar calendar = Calendar.getInstance(); 15 | calendar.setTime(new Date(time)); 16 | double minute = calendar.get(Calendar.MINUTE); 17 | double second = calendar.get(Calendar.SECOND); 18 | 19 | DecimalFormat format = new DecimalFormat("00"); 20 | return format.format(minute) + ":" + format.format(second); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/layer_recording_animation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_recodering_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_recoder_btn_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_recoder_btn_recoding.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_window_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 18 | 19 | 27 | 28 | 34 | 35 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_list_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 21 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_recoder_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | 22 | 23 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WuLiFei/AudioRecoder/018ed026e7d6f3220851fdef797f090808ebe8a4/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WuLiFei/AudioRecoder/018ed026e7d6f3220851fdef797f090808ebe8a4/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WuLiFei/AudioRecoder/018ed026e7d6f3220851fdef797f090808ebe8a4/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/icon_microphone_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WuLiFei/AudioRecoder/018ed026e7d6f3220851fdef797f090808ebe8a4/app/src/main/res/mipmap-xhdpi/icon_microphone_normal.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/icon_microphone_recoding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WuLiFei/AudioRecoder/018ed026e7d6f3220851fdef797f090808ebe8a4/app/src/main/res/mipmap-xhdpi/icon_microphone_recoding.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WuLiFei/AudioRecoder/018ed026e7d6f3220851fdef797f090808ebe8a4/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WuLiFei/AudioRecoder/018ed026e7d6f3220851fdef797f090808ebe8a4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | > 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 16dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AudioRecoder 3 | Settings 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 |