Android實(shí)現(xiàn)測試環(huán)境噪音分貝
本文實(shí)例為大家分享了Android實(shí)現(xiàn)測試環(huán)境噪音分貝的具體代碼,供大家參考,具體內(nèi)容如下
前言:
最近做工具類項(xiàng)目,手機(jī)上小工具各種,有一個(gè)測量環(huán)境噪音分貝值的,個(gè)人對機(jī)車碼表式顯示忠愛(有點(diǎn)機(jī)車情節(jié)),網(wǎng)上和Android APP market 轉(zhuǎn)了一圈盡沒發(fā)現(xiàn)讓人心動(dòng)了。所以只能自己動(dòng)手,做圖,做定義控件去實(shí)現(xiàn)。
具體實(shí)現(xiàn)如下:
素材準(zhǔ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>
自定義控件類:核心思路其實(shí)就是對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ì)量差了些,但效果算達(dá)到預(yù)期,由于聲音分貝值本身變化是線性的,所以即使這里我沒有加入動(dòng)畫效果,指針的轉(zhuǎn)動(dòng)線性也是令人可以接受的。另外可惜沒做好gif 圖檔上傳。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android8.1 源碼修改之插入SIM卡默認(rèn)啟用Volte功能
這篇文章主要介紹了Android8.1 源碼修改之插入SIM卡默認(rèn)啟用Volte功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05
Android用tabhost實(shí)現(xiàn) 界面切換,每個(gè)界面為一個(gè)獨(dú)立的activity操作
這篇文章主要介紹了Android用tabhost實(shí)現(xiàn) 界面切換,每個(gè)界面為一個(gè)獨(dú)立的activity操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
Android ImageView隨手勢變化動(dòng)態(tài)縮放圖片
這篇文章主要為大家詳細(xì)介紹了Android ImageView隨手勢變化動(dòng)態(tài)縮放圖片的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-05-05

