Android實現(xiàn)測試環(huán)境噪音分貝
本文實例為大家分享了Android實現(xiàn)測試環(huán)境噪音分貝的具體代碼,供大家參考,具體內(nèi)容如下
前言:
最近做工具類項目,手機上小工具各種,有一個測量環(huán)境噪音分貝值的,個人對機車碼表式顯示忠愛(有點機車情節(jié)),網(wǎng)上和Android APP market 轉(zhuǎn)了一圈盡沒發(fā)現(xiàn)讓人心動了。所以只能自己動手,做圖,做定義控件去實現(xiàn)。
具體實現(xiàn)如下:
素材準備:
自定義控件 xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ? ? android:layout_width="fill_parent" ? ? android:layout_height="fill_parent" ? ? android:gravity="center" ? ? android:orientation="vertical"> ? ? <ImageView ? ? ? ? android:id="@+id/panel" ? ? ? ? android:layout_width="300dp" ? ? ? ? android:layout_height="300dp" ? ? ? ? android:layout_centerHorizontal="true" ? ? ? ? android:layout_centerVertical="true" ? ? ? ? android:scaleType="fitCenter" ? ? ? ? android:src="@drawable/panel__green" /> ? ? <ImageView ? ? ? ? android:id="@+id/pointer" ? ? ? ? android:layout_width="wrap_content" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_centerHorizontal="true" ? ? ? ? android:layout_centerInParent="true" ? ? ? ? android:layout_gravity="center_horizontal" ? ? ? ? android:alpha="0.8" ? ? ? ? android:scaleType="centerInside" ? ? ? ? android:src="@drawable/pointer" /> ? ? <LinearLayout ? ? ? ? android:layout_centerHorizontal="true" ? ? ? ? android:layout_width="wrap_content" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:paddingTop="50dp" ? ? ? ? android:layout_centerVertical="true"> ? ? ? ? <TextView ? ? ? ? ? ? android:id="@+id/value" ? ? ? ? ? ? android:layout_width="wrap_content" ? ? ? ? ? ? android:layout_height="wrap_content" ? ? ? ? ? ? android:layout_centerHorizontal="true" ? ? ? ? ? ? android:text="welcome to use Nosy test !" /> ? ? ? ? <TextView ? ? ? ? ? ? android:id="@+id/maxvalue" ? ? ? ? ? ? android:layout_width="wrap_content" ? ? ? ? ? ? android:layout_height="wrap_content" ? ? ? ? ? ? android:layout_centerHorizontal="true" ? ? ? ? ? ? android:paddingLeft="20dp" ? ? ? ? ? ? android:text="MAX:" /> ? ? </LinearLayout> </RelativeLayout>
自定義控件類:核心思路其實就是對ImageView 圖片的旋轉(zhuǎn)
public class PlateView extends RelativeLayout { ? ? public void setmMaxValue(double mMaxValue) { ? ? ? ? this.mMaxValue = mMaxValue; ? ? } ? ? private double mMaxValue =0; ? ? private ImageView mPanel; ? ? private ImageView mPointer; ? ? private TextView textView; ? ? private TextView maxTextView; ? ? private Matrix matrix = new Matrix(); ? ? private Context mContext; ? ? private double mLastValue = 50; ? ? public double getValue() { ? ? ? ? return value; ? ? } ? ? public void setValue(double value) { ? ? ? ? mLastValue = this.value; ? ? ? ? this.value = value; ? ? ? ? if(Math.abs(mMaxValue)<Math.abs(this.value)){ ? ? ? ? ? ? mMaxValue = this.value; ? ? ? ? } ? ? ? ? show(); ? ? } ? ? private double value = 50; ? ? public PlateView(Context context) { ? ? ? ? super(context); ? ? } ? ? public PlateView(Context context, AttributeSet attrs) { ? ? ? ? super(context, attrs); ? ? ? ? mContext = context; ? ? ? ? LayoutInflater layoutInflater = (LayoutInflater) context. ? ? ? ? ? ? ? ? getSystemService(Context.LAYOUT_INFLATER_SERVICE); ? ? ? ? layoutInflater.inflate(R.layout.plate, this); ? ? ? ? mPanel = (ImageView) findViewById(R.id.panel); ? ? ? ? mPointer = (ImageView) findViewById(R.id.pointer); ? ? ? ? textView=(TextView) findViewById(R.id.value); ? ? ? ? maxTextView=(TextView) findViewById(R.id.maxvalue); ? ? ? ? show(); ? ? } ? ? public void show() { ? ? ? ? float rotate = (float) (getValue() - this.mLastValue); ? ? ? ? if (Math.abs(rotate) > 0.1) { ? ? ? ? ? ? mPointer.setScaleType(ImageView.ScaleType.MATRIX); //required ? ? ? ? ? ? matrix.postRotate(rotate*8/5, mPointer.getWidth() / 2, mPointer.getHeight() / 2); ? ? ? ? ? ? mPointer.setImageMatrix(matrix); ? ? ? ? ? ? textView.setText(getValueText(getValue())); ? ? ? ? ? ? maxTextView.setText("MAX:"+getValueText(this.mMaxValue)); ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? requestLayout(); ? ? ? ? } ? ? } ? ? private String getValueText(double value){ ? ? ? ? value+=0.0000001; ? ? ? ? String sRes =value+""; ? ? ? ? if(sRes.contains(".")){ ? ? ? ? ? ? sRes = sRes.substring(0,sRes.indexOf(".")+3); ? ? ? ? } ? ? ? ? return sRes; ? ? } ? ? public int dip2px(Context context, float dpValue) { ? ? ? ? final float scale = context.getResources().getDisplayMetrics().density; ? ? ? ? return (int) (dpValue * scale + 0.5f); ? ? } ? ? public static int px2dip(Context context, float pxValue) { ? ? ? ? final float scale = context.getResources().getDisplayMetrics().density; ? ? ? ? return (int) (pxValue / scale + 0.5f); ? ? } }
分貝測量類:
public class AudioRecordDemo { ? ? private static final String TAG = "AudioRecord"; ? ? static final int SAMPLE_RATE_IN_HZ = 8000; ? ? static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ, ? ? ? ? ? ? AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT); ? ? AudioRecord mAudioRecord; ? ? boolean isGetVoiceRun; ? ? Object mLock; ? ? private WeakReference<MainActivity> mActivity; ? ? public AudioRecordDemo(MainActivity activity) { ? ? ? ? mLock = new Object(); ? ? ? ? mActivity = new WeakReference<>(activity); ? ? } ? ? public void sotp() { ? ? ? ? this.isGetVoiceRun = false; ? ? } ? ? public void getNoiseLevel() { ? ? ? ? if (isGetVoiceRun) { ? ? ? ? ? ? return; ? ? ? ? } ? ? ? ? mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, ? ? ? ? ? ? ? ? SAMPLE_RATE_IN_HZ, AudioFormat.CHANNEL_IN_DEFAULT, ? ? ? ? ? ? ? ? AudioFormat.ENCODING_PCM_16BIT, BUFFER_SIZE); ? ? ? ? if (mAudioRecord == null) { ? ? ? ? } ? ? ? ? isGetVoiceRun = true; ? ? ? ? new Thread(new Runnable() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? mAudioRecord.startRecording(); ? ? ? ? ? ? ? ? short[] buffer = new short[BUFFER_SIZE]; ? ? ? ? ? ? ? ? final MainActivity activity = mActivity.get(); ? ? ? ? ? ? ? ? while (isGetVoiceRun) { ? ? ? ? ? ? ? ? ? ? int r = mAudioRecord.read(buffer, 0, BUFFER_SIZE); ? ? ? ? ? ? ? ? ? ? long v = 0; ? ? ? ? ? ? ? ? ? ? for (int i = 0; i < buffer.length; i++) { ? ? ? ? ? ? ? ? ? ? ? ? v += buffer[i] * buffer[i]; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? double mean = v / (double) r; ? ? ? ? ? ? ? ? ? ? final double volume = 10 * Math.log10(mean); ? ? ? ? ? ? ? ? ? ? Log.d(TAG, "db value:" + volume); ? ? ? ? ? ? ? ? ? ? if (null != activity) { ? ? ? ? ? ? ? ? ? ? ? ? activity.runOnUiThread(new Runnable() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? activity.plateView.setValue(volume); ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? // 大概一秒十次 ? ? ? ? ? ? ? ? ? ? synchronized (mLock) { ? ? ? ? ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? ? ? ? ? mLock.wait(100); ? ? ? ? ? ? ? ? ? ? ? ? } catch (InterruptedException e) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? mAudioRecord.stop(); ? ? ? ? ? ? ? ? mAudioRecord.release(); ? ? ? ? ? ? ? ? mAudioRecord = null; ? ? ? ? ? ? ? ? if (null != activity) { ? ? ? ? ? ? ? ? ? ? activity.runOnUiThread(new Runnable() { ? ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? activity.plateView.setmMaxValue(0); ? ? ? ? ? ? ? ? ? ? ? ? ? ? activity.plateView.setValue(1); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }).start(); ? ? } }
記得加入Manifest 權(quán)限:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Layout使用控件:
<com.asus.function.antitouch.sound.PlateView ? ? android:id="@+id/soundplate" ? ? android:layout_width="wrap_content" ? ? android:layout_height="wrap_content" ? ? android:layout_below="@+id/start"/>
Activity中代碼:
audioRecordDemo = new AudioRecordDemo(this); ? ? plateView = (PlateView) findViewById(R.id.soundplate); ? ? start.setOnClickListener(new View.OnClickListener() { ? ? ? ? @Override ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? if (start.getText().toString().equalsIgnoreCase(STOP)) { ? ? ? ? ? ? ? ? audioRecordDemo.sotp(); ? ? ? ? ? ? ? ? start.setText(START); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? audioRecordDemo.getNoiseLevel(); ? ? ? ? ? ? ? ? start.setText(STOP); ? ? ? ? ? ? } ? ? ? ? } ? ? }); }
APP 效果圖:
結(jié)語:
圖片素材質(zhì)量差了些,但效果算達到預(yù)期,由于聲音分貝值本身變化是線性的,所以即使這里我沒有加入動畫效果,指針的轉(zhuǎn)動線性也是令人可以接受的。另外可惜沒做好gif 圖檔上傳。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android8.1 源碼修改之插入SIM卡默認啟用Volte功能
這篇文章主要介紹了Android8.1 源碼修改之插入SIM卡默認啟用Volte功能,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-05-05Android用tabhost實現(xiàn) 界面切換,每個界面為一個獨立的activity操作
這篇文章主要介紹了Android用tabhost實現(xiàn) 界面切換,每個界面為一個獨立的activity操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09Android ImageView隨手勢變化動態(tài)縮放圖片
這篇文章主要為大家詳細介紹了Android ImageView隨手勢變化動態(tài)縮放圖片的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-05-05