編輯:關於Android編程
package com.oyp.media; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Rect; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.audiofx.BassBoost; import android.media.audiofx.Equalizer; import android.media.audiofx.PresetReverb; import android.media.audiofx.Visualizer; import android.os.Bundle; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.Spinner; import android.widget.TextView; public class MediaPlayerTest extends Activity { // 定義播放聲音的MediaPlayer private MediaPlayer mPlayer; // 定義系統的頻譜 private Visualizer mVisualizer; // 定義系統的均衡器 private Equalizer mEqualizer; // 定義系統的重低音控制器 private BassBoost mBass; // 定義系統的預設音場控制器 private PresetReverb mPresetReverb; private LinearLayout layout; private ListreverbNames = new ArrayList (); private List reverbVals = new ArrayList (); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //設置音頻流 - STREAM_MUSIC:音樂回放即媒體音量 setVolumeControlStream(AudioManager.STREAM_MUSIC); layout = new LinearLayout(this);//代碼創建布局 layout.setOrientation(LinearLayout.VERTICAL);//設置為線性布局-上下排列 setContentView(layout);//將布局添加到 Activity // 創建MediaPlayer對象,並添加音頻 // 音頻路徑為 res/raw/beautiful.mp3 mPlayer = MediaPlayer.create(this, R.raw.beautiful); // 初始化示波器 setupVisualizer(); // 初始化均衡控制器 setupEqualizer(); // 初始化重低音控制器 setupBassBoost(); // 初始化預設音場控制器 setupPresetReverb(); // 開發播放音樂 mPlayer.start(); } /** * 初始化頻譜 */ private void setupVisualizer() { // 創建MyVisualizerView組件,用於顯示波形圖 final MyVisualizerView mVisualizerView = new MyVisualizerView(this); mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, (int) (120f * getResources().getDisplayMetrics().density))); // 將MyVisualizerView組件添加到layout容器中 layout.addView(mVisualizerView); // 以MediaPlayer的AudioSessionId創建Visualizer // 相當於設置Visualizer負責顯示該MediaPlayer的音頻數據 mVisualizer = new Visualizer(mPlayer.getAudioSessionId()); //設置需要轉換的音樂內容長度,專業的說這就是采樣,該采樣值一般為2的指數倍,如64,128,256,512,1024。 mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]); // 為mVisualizer設置監聽器 /* * Visualizer.setDataCaptureListener(OnDataCaptureListener listener, int rate, boolean waveform, boolean fft * * listener,表監聽函數,匿名內部類實現該接口,該接口需要實現兩個函數 rate, 表示采樣的周期,即隔多久采樣一次,聯系前文就是隔多久采樣128個數據 iswave,是波形信號 isfft,是FFT信號,表示是獲取波形信號還是頻域信號 */ mVisualizer.setDataCaptureListener( new Visualizer.OnDataCaptureListener() { //這個回調應該采集的是快速傅裡葉變換有關的數據 @Override public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) { } //這個回調應該采集的是波形數據 @Override public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) { // 用waveform波形數據更新mVisualizerView組件 mVisualizerView.updateVisualizer(waveform); } }, Visualizer.getMaxCaptureRate() / 2, true, false); mVisualizer.setEnabled(true); } /** * 初始化均衡控制器 */ private void setupEqualizer() { // 以MediaPlayer的AudioSessionId創建Equalizer // 相當於設置Equalizer負責控制該MediaPlayer mEqualizer = new Equalizer(0, mPlayer.getAudioSessionId()); // 啟用均衡控制效果 mEqualizer.setEnabled(true); TextView eqTitle = new TextView(this); eqTitle.setText(均衡器:); layout.addView(eqTitle); // 獲取均衡控制器支持最小值和最大值 final short minEQLevel = mEqualizer.getBandLevelRange()[0];//第一個下標為最低的限度范圍 short maxEQLevel = mEqualizer.getBandLevelRange()[1]; // 第二個下標為最高的限度范圍 // 獲取均衡控制器支持的所有頻率 short brands = mEqualizer.getNumberOfBands(); for (short i = 0; i < brands; i++) { TextView eqTextView = new TextView(this); // 創建一個TextView,用於顯示頻率 eqTextView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); eqTextView.setGravity(Gravity.CENTER_HORIZONTAL); // 設置該均衡控制器的頻率 eqTextView.setText((mEqualizer.getCenterFreq(i) / 1000) + Hz); layout.addView(eqTextView); // 創建一個水平排列組件的LinearLayout LinearLayout tmpLayout = new LinearLayout(this); tmpLayout.setOrientation(LinearLayout.HORIZONTAL); // 創建顯示均衡控制器最小值的TextView TextView minDbTextView = new TextView(this); minDbTextView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); // 顯示均衡控制器的最小值 minDbTextView.setText((minEQLevel / 100) + dB); // 創建顯示均衡控制器最大值的TextView TextView maxDbTextView = new TextView(this); maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); // 顯示均衡控制器的最大值 maxDbTextView.setText((maxEQLevel / 100) + dB); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.weight = 1; // 定義SeekBar做為調整工具 SeekBar bar = new SeekBar(this); bar.setLayoutParams(layoutParams); bar.setMax(maxEQLevel - minEQLevel); bar.setProgress(mEqualizer.getBandLevel(i)); final short brand = i; // 為SeekBar的拖動事件設置事件監聽器 bar.setOnSeekBarChangeListener(new SeekBar .OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // 設置該頻率的均衡值 mEqualizer.setBandLevel(brand, (short) (progress + minEQLevel)); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); // 使用水平排列組件的LinearLayout“盛裝”3個組件 tmpLayout.addView(minDbTextView); tmpLayout.addView(bar); tmpLayout.addView(maxDbTextView); // 將水平排列組件的LinearLayout添加到myLayout容器中 layout.addView(tmpLayout); } } /** * 初始化重低音控制器 */ private void setupBassBoost() { // 以MediaPlayer的AudioSessionId創建BassBoost // 相當於設置BassBoost負責控制該MediaPlayer mBass = new BassBoost(0, mPlayer.getAudioSessionId()); // 設置啟用重低音效果 mBass.setEnabled(true); TextView bbTitle = new TextView(this); bbTitle.setText(重低音:); layout.addView(bbTitle); // 使用SeekBar做為重低音的調整工具 SeekBar bar = new SeekBar(this); // 重低音的范圍為0~1000 bar.setMax(1000); bar.setProgress(0); // 為SeekBar的拖動事件設置事件監聽器 bar.setOnSeekBarChangeListener(new SeekBar .OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar , int progress, boolean fromUser) { // 設置重低音的強度 mBass.setStrength((short) progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); layout.addView(bar); } /** * 初始化預設音場控制器 */ private void setupPresetReverb() { // 以MediaPlayer的AudioSessionId創建PresetReverb // 相當於設置PresetReverb負責控制該MediaPlayer mPresetReverb = new PresetReverb(0, mPlayer.getAudioSessionId()); // 設置啟用預設音場控制 mPresetReverb.setEnabled(true); TextView prTitle = new TextView(this); prTitle.setText(音場); layout.addView(prTitle); // 獲取系統支持的所有預設音場 for (short i = 0; i < mEqualizer.getNumberOfPresets(); i++) { reverbNames.add(i); reverbVals.add(mEqualizer.getPresetName(i)); } // 使用Spinner做為音場選擇工具 Spinner sp = new Spinner(this); sp.setAdapter(new ArrayAdapter (MediaPlayerTest.this, android.R.layout.simple_spinner_item, reverbVals)); // 為Spinner的列表項選中事件設置監聽器 sp.setOnItemSelectedListener(new Spinner .OnItemSelectedListener() { @Override public void onItemSelected(AdapterView arg0 , View arg1, int arg2, long arg3) { // 設定音場 mPresetReverb.setPreset(reverbNames.get(arg2)); } @Override public void onNothingSelected(AdapterView arg0) { } }); layout.addView(sp); } @Override protected void onPause() { super.onPause(); if (isFinishing() && mPlayer != null) { // 釋放所有對象 mVisualizer.release(); mEqualizer.release(); mPresetReverb.release(); mBass.release(); mPlayer.release(); mPlayer = null; } } /** * 根據Visualizer傳來的數據動態繪制波形效果,分別為: * 塊狀波形、柱狀波形、曲線波形 */ private static class MyVisualizerView extends View { // bytes數組保存了波形抽樣點的值 private byte[] bytes; private float[] points; private Paint paint = new Paint(); private Rect rect = new Rect(); private byte type = 0; public MyVisualizerView(Context context) { super(context); bytes = null; // 設置畫筆的屬性 paint.setStrokeWidth(1f); paint.setAntiAlias(true);//抗鋸齒 paint.setColor(Color.YELLOW);//畫筆顏色 paint.setStyle(Style.FILL); } public void updateVisualizer(byte[] ftt) { bytes = ftt; // 通知該組件重繪自己。 invalidate(); } @Override public boolean onTouchEvent(MotionEvent me) { // 當用戶觸碰該組件時,切換波形類型 if(me.getAction() != MotionEvent.ACTION_DOWN) { return false; } type ++; if(type >= 3) { type = 0; } return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (bytes == null) { return; } // 繪制白色背景 canvas.drawColor(Color.WHITE); // 使用rect對象記錄該組件的寬度和高度 rect.set(0,0,getWidth(),getHeight()); switch(type) { // -------繪制塊狀的波形圖------- case 0: for (int i = 0; i < bytes.length - 1; i++) { float left = getWidth() * i / (bytes.length - 1); // 根據波形值計算該矩形的高度 float top = rect.height()-(byte)(bytes[i+1]+128) * rect.height() / 128; float right = left + 1; float bottom = rect.height(); canvas.drawRect(left, top, right, bottom, paint); } break; // -------繪制柱狀的波形圖(每隔18個抽樣點繪制一個矩形)------- case 1: for (int i = 0; i < bytes.length - 1; i += 18) { float left = rect.width()*i/(bytes.length - 1); // 根據波形值計算該矩形的高度 float top = rect.height()-(byte)(bytes[i+1]+128) * rect.height() / 128; float right = left + 6; float bottom = rect.height(); canvas.drawRect(left, top, right, bottom, paint); } break; // -------繪制曲線波形圖------- case 2: // 如果point數組還未初始化 if (points == null || points.length < bytes.length * 4) { points = new float[bytes.length * 4]; } for (int i = 0; i < bytes.length - 1; i++) { // 計算第i個點的x坐標 points[i * 4] = rect.width()*i/(bytes.length - 1); // 根據bytes[i]的值(波形點的值)計算第i個點的y坐標 points[i * 4 + 1] = (rect.height() / 2) + ((byte) (bytes[i] + 128)) * 128 / (rect.height() / 2); // 計算第i+1個點的x坐標 points[i * 4 + 2] = rect.width() * (i + 1) / (bytes.length - 1); // 根據bytes[i+1]的值(波形點的值)計算第i+1個點的y坐標 points[i * 4 + 3] = (rect.height() / 2) + ((byte) (bytes[i + 1] + 128)) * 128 / (rect.height() / 2); } // 繪制波形曲線 canvas.drawLines(points, paint); break; } } } }
java.lang.RuntimeException: Cannot initialize Visualizer engine, error: -4
先來看看網易新聞客戶端以及自己實現的效果圖,效果當然還是網易的好gridviewsort.gif如何實現拖拽一個Item用WindowManager添加一個ImageVi
本文實例講述了Android編程獲取GPS數據的方法。分享給大家供大家參考,具體如下:GPS是Android系統中重要的組成部分,通過它可以衍生出眾多的與位置相關的應用。
LinearLayout是Android控件中的線性布局控件,它包含的子控件將以橫向(HORIZONTAL)或豎向(VERTICAL)的方式排
本節學習使用C語言調用JAVA語言。在生活中比如我們某些底層的硬件必須使用C語言去編寫,當C語言返回的某些數值顯示在界面上時,就比如使用JNI。這樣可以將C返回的值顯示在