ubuntu安装BCM4313无线驱动

OS : ubuntu 12.04

sudo apt-get install --reinstall linux-headers-generic linux-headers-`uname -r`
sudo apt-get install --reinstall bcmwl-kernel-source
sudo modprobe wl

MediaPlayer 处理网络音频文件

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=".MainActivity" >

    <TextView
        android:id="@+id/TV01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Status :" />

    <TextView
        android:id="@+id/statusTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Unknown" />

    <TextView
        android:id="@+id/bufferPercentTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Buffer Percentage : " />

    <ProgressBar
        android:id="@+id/bufferSB"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:max="100" />

    <Button
        android:id="@+id/startBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start" />

    <Button
        android:id="@+id/stopBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Stop" />

</LinearLayout>

main_activity.java

public class MainActivity extends Activity implements OnCompletionListener,
		OnBufferingUpdateListener, OnClickListener, OnPreparedListener,
		OnErrorListener {

	Button startBtn;
	Button stopBtn;
	TextView statusTV;
	ProgressBar bufferSB;
	MediaPlayer mediaPlayer;

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

		startBtn = (Button) findViewById(R.id.startBtn);
		startBtn.setOnClickListener(this);
		startBtn.setEnabled(false);

		stopBtn = (Button) findViewById(R.id.stopBtn);
		stopBtn.setOnClickListener(this);
		stopBtn.setEnabled(false);

		statusTV = (TextView) findViewById(R.id.statusTV);
		statusTV.setText("Creating mediaPlayer");

		bufferSB = (ProgressBar) findViewById(R.id.bufferSB);

		mediaPlayer = new MediaPlayer();
		mediaPlayer.setOnCompletionListener(this);
		mediaPlayer.setOnBufferingUpdateListener(this);
		mediaPlayer.setOnPreparedListener(this);
		mediaPlayer.setOnErrorListener(this);

		statusTV.setText("Created mediaPlayer");

		statusTV.setText("seting DataSource");
		try {
			mediaPlayer.setDataSource("http://lnmcc.net/wordpress/wp-content/uploads/2013/10/Rolling-In-The-Deep.mp3");
			statusTV.setText("setted DataSource");

			statusTV.setText("calling prepareAsync");
			// 不同于prepare(), prepareAsync()会立即返回,后台开始缓冲
			mediaPlayer.prepareAsync();
		} catch (IOException e) {
			Log.v("mediaPlayer.setDataSource", e.getMessage());
		}
	}

	@Override
	public void onClick(View v) {

		if (v == startBtn) {
			mediaPlayer.start();
			statusTV.setText("start play");

			startBtn.setEnabled(false);
			stopBtn.setEnabled(true);
		} else if (v == stopBtn) {
			mediaPlayer.pause();
			statusTV.setText("pause play");

			stopBtn.setEnabled(false);
			startBtn.setEnabled(true);
		}
	}

	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {

		statusTV.setText("invoke onError");

		switch (what) {
		case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
			statusTV.setText("MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK" + extra);
			break;
		case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
			statusTV.setText("MEDIA_ERROR_SERVER_DIED" + extra);
			break;
		case MediaPlayer.MEDIA_ERROR_UNSUPPORTED:
			statusTV.setText("MEDIA_ERROR_UNSUPPORTED" + extra);
			break;
		case MediaPlayer.MEDIA_ERROR_UNKNOWN:
			statusTV.setText("MEDIA_ERROR_UNKNOWN" + extra);
			break;
		}
		return false;
	}

	@Override
	public void onCompletion(MediaPlayer mp) {

		statusTV.setText("invoke onCompletion");
		stopBtn.setEnabled(false);
		startBtn.setEnabled(true);
	}

	@Override
	// 当后台缓冲数据发生变化时,会调用这个方法
	public void onBufferingUpdate(MediaPlayer mp, int percent) {
		bufferSB.setProgress(percent);
	}
	
	@Override
	//数据缓冲完成,可以播放
	public void onPrepared(MediaPlayer mp) {
		
		statusTV.setText("invoke onPrepared");
		startBtn.setEnabled(true);
	}

}

最后要在AndroidManifest.xml中加入Internet权限:

<uses-permission android:name="android.permission.INTERNET" />

git clone https://github.com/lnmcc/NetAudioPlayerExample.git

Android 音乐文件搜索和播放

main_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/returnBtn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="return" />

    <!-- 如果在代码中需要使用simple_list_item布局,那么这里的id必须为list -->

    <ListView
        android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

Main_activity.java

public class MainActivity extends ListActivity implements LoaderCallbacks<Cursor> {
	
	//设置俩种选项状态:选择专辑或者选择歌曲
	public static int STATE_SELECT_ALBUM = 0;
	public static int STATE_SELECT_SONG = 1;
	//默认当前状态为选择专辑
	int currentState = STATE_SELECT_ALBUM;
	//查询专辑
	static final String[] AlbumColumns = {
		MediaStore.Audio.Albums._ID,
		MediaStore.Audio.Albums.ALBUM,
	};
	//查询歌曲
	static final String[] songColumns = {
		MediaStore.Audio.Media.DATA,
		MediaStore.Audio.Media._ID,
		MediaStore.Audio.Media.TITLE,
		MediaStore.Audio.Media.DISPLAY_NAME,
		MediaStore.Audio.Media.MIME_TYPE,
	};
	
	Cursor cursor;
	SimpleCursorAdapter mAdapter;
	Button returnBtn;
	MediaPlayer mediaPlayer;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		returnBtn = (Button)findViewById(R.id.returnBtn);
		returnBtn.setOnClickListener(new View.OnClickListener() {
			//处理返回上级目录
			@Override
			public void onClick(View v) {
				if(currentState == STATE_SELECT_ALBUM) {
					//do nothing
				} else if(currentState == STATE_SELECT_SONG) {
					QueryAlbum();
					currentState = STATE_SELECT_ALBUM;
				}
			}
		});
		
	    //getLoaderManager().initLoader(0, null, this);
		QueryAlbum();
	}
	
	private void QueryAlbum() {
		
		//显示专辑查询结果
		String[] displayFields = new String[] {MediaStore.Audio.Albums.ALBUM};
		int[] displayViews = new int[] {android.R.id.text1};
		
	    mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, null, displayFields, displayViews, 0);
	    Bundle b = new Bundle();
	    b.putInt("state", STATE_SELECT_ALBUM);
	    getLoaderManager().restartLoader(0, b, this);
	    setListAdapter(mAdapter);
	}

	@Override
	public Loader<Cursor> onCreateLoader(int id, Bundle args) {
		
		Loader<Cursor> loader = null;
		if(args.getInt("state") == STATE_SELECT_ALBUM) {
			loader =  new CursorLoader(this, MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, AlbumColumns, null, null, null);
		} else if(args.getInt("state") == STATE_SELECT_SONG) {
			String where = args.getString("where");
			String whereVal[] = args.getStringArray("whereVal");
			String orderBy = args.getString("orderBy");
			loader =  new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songColumns, where, whereVal, orderBy);
		}
		return loader;
	}
	
	@Override
	public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
		cursor = data;
		mAdapter.swapCursor(data);
	}
	
	@Override
	public void onLoaderReset(Loader<Cursor> loader) {
		mAdapter.swapCursor(null);
	}
	
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		
		if(currentState == STATE_SELECT_ALBUM) {
			
			if(cursor.moveToPosition(position)) {
				String where = MediaStore.Audio.Media.ALBUM + "=?";
				String whereVal[] = {cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM))};
				String orderBy = MediaStore.Audio.Media.TITLE;
				String[] displayFileds = {MediaStore.Audio.Media.DISPLAY_NAME};
				int[] displayViews = new int[] {android.R.id.text1};
				
				mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, null, displayFileds, displayViews, 0);
				Bundle b = new Bundle();
				b.putInt("state", STATE_SELECT_SONG);
				b.putString("where", where);
				b.putStringArray("whereVal", whereVal);
				b.putString("orderBy", orderBy);
				getLoaderManager().restartLoader(0, b, this);
				setListAdapter(mAdapter);
				//进入专辑后,下一次选择模式一定是选择歌曲
				currentState = STATE_SELECT_SONG;
			}
		} else if(currentState == STATE_SELECT_SONG) {
			
			if(cursor.moveToPosition(position)) {
				int fileColumn = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
				int mimeTypeColumn = cursor.getColumnIndex(MediaStore.Audio.Media.MIME_TYPE);
				String audioFilePath = cursor.getString(fileColumn);
				String mimeType = cursor.getString(mimeTypeColumn);
				File audioFile = new File(audioFilePath);
				
				//打开下面3行可以使用外部播放器播放音频
				//Intent i = new Intent(android.content.Intent.ACTION_VIEW);
				//i.setDataAndType(Uri.fromFile(audioFile), mimeType);
				//startActivity(i);
				
				//使用MediaPlayer播放音频
				if(null != mediaPlayer && mediaPlayer.isPlaying()) {
					mediaPlayer.stop();
					mediaPlayer.release();
				}
				mediaPlayer = MediaPlayer.create(this, Uri.fromFile(audioFile));
				mediaPlayer.start();
			}
		}
	}

	@Override
	protected void onStop() {
		super.onStop();
		if(null != mediaPlayer) {
			mediaPlayer.start();
			mediaPlayer.release();
		}
	}
}

git clone https://github.com/lnmcc/AudioBrowserAndPlayExample.git

Android使用多点触摸之绘图板

activity_main.xml

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</RelativeLayout>

MainAvtivity.java

public class MainActivity extends Activity implements OnTouchListener{

	ImageView imageView;
	Bitmap bitmap;
	Canvas canvas;
	Paint paint;

	float startx = 0f;
	float starty = 0f;
	float endx = 0f;
	float endy = 0f;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//全屏显示
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		//横屏显示
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		setContentView(R.layout.activity_main);

		imageView = (ImageView)findViewById(R.id.imageView);
		Display display = getWindowManager().getDefaultDisplay();

		bitmap = Bitmap.createBitmap(display.getWidth(), display.getHeight(), Bitmap.Config.ARGB_8888);
		canvas = new Canvas(bitmap);
		//设置画笔
		paint = new Paint();
		paint.setColor(Color.RED);
		paint.setStrokeWidth(5);
		imageView.setImageBitmap(bitmap);
		imageView.setOnTouchListener(this);
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {

		switch(event.getAction()){

		case MotionEvent.ACTION_DOWN:
			startx = event.getX();
			starty = event.getY();
			break;

		case MotionEvent.ACTION_UP:
			break;

		case MotionEvent.ACTION_MOVE:
			endx = event.getX();
			endy = event.getY();

			canvas.drawLine(startx, starty, endx, endy, paint);
			//重绘图像
			imageView.invalidate();
			//重新设置起始坐标
			startx = endx;
			starty = endy;
			break;

		case MotionEvent.ACTION_CANCEL:
			break;

	    default:
			break;
		}

		return true;
	}
}

git clone https://github.com/lnmcc/TouchDrawExample.git

Android图像编辑和处理之调整图像明亮度

ColorMatrix是一个4 x 5的矩阵,M' = M * CM
M' = (R', G', B', A') : 为结果颜色矩阵;
M = (R, G, B, A) : 为源颜色矩阵;
CM = (a11 a12 a13 a14 a15)
(a21 a22 a23 a24 a25)
(a31 a32 a33 a34 a35)
(a41 a42 a43 a44 a45) : 为转换矩阵(ColorMatrix);
ColorMatrix的前4列作用于R, G, B, A, 第五列作用与亮度值。
通过ColorMatrix 不仅可以调整亮度还可以调整各个颜色值。

使用ColorMatrix的基本步骤 :

  1. 定义一个ColorMatrix : ColorMatrix cm = new ColorMatrix()
  2. 设置我们需要的颜色转化矩阵 : cm.set(new float[]{})
  3. 给当前Paint设置ColorFilter : paint.setColorFilter(new ColorMatrixColorFilter(cm))
  4. 使用设置好的Paint绘图

activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/ChoosePictureButton"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Choose Picture" />

        <SeekBar
            android:id="@+id/brightnessSB"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/ChoosePictureButton"
            android:max="200"
            android:progress="100" />
    </RelativeLayout>

    <ImageView
        android:id="@+id/ChooseImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ImageView
        android:id="@+id/AlteredImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

alt none

MainActivity.java:

public class MainActivity extends Activity implements OnClickListener {

	private static final int REQUEST_CODE = 0;

	ImageView chosenImageView;
	ImageView alteredImageView;

	Bitmap alteredBitmap;
	Bitmap bmp;

	Button choosePicture;
	//亮度
	float brightness;

	//调节亮度的进度条
	SeekBar brightnessSB;

	Canvas canvas;
	Paint paint;
	ColorMatrix cm;
	Matrix matrix;

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

		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

		alteredImageView = (ImageView) findViewById(R.id.AlteredImageView);
		chosenImageView = (ImageView) findViewById(R.id.ChooseImageView);
		choosePicture = (Button) findViewById(R.id.ChoosePictureButton);
		choosePicture.setOnClickListener(this);
		//变换矩阵,可以通过这个矩阵做很多图像缩放、平移和旋转等操作
		matrix = new Matrix();
		//颜色矩阵
		cm = new ColorMatrix();
		//画笔
		paint = new Paint();
		paint.setColorFilter(new ColorMatrixColorFilter(cm));

		brightnessSB = (SeekBar) findViewById(R.id.brightnessSB);
		brightnessSB.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

					@Override
					public void onStopTrackingTouch(SeekBar seekBar) {
					}

					@Override
					public void onStartTrackingTouch(SeekBar seekBar) {
					}

					@Override
					public void onProgressChanged(SeekBar seekBar,
							int progress, boolean fromUser) {

						if (null != bmp) {
							//seekbar的范围为[0, 200]
							//brightness的范围为[-100, 100]
							brightness = (float) (progress - 100);
							cm.set(new float[] { 1, 0, 0, 0, brightness,
									             0, 1, 0, 0, brightness, 
									             0, 0,1, 0, brightness, 
									             0, 0, 0, 1, 0 });

							paint.setColorFilter(new ColorMatrixColorFilter(cm));
							canvas.drawBitmap(bmp, matrix, paint);
							alteredImageView.setImageBitmap(alteredBitmap);
						} else {
							brightnessSB.setProgress(100);
						}
					}
				});
	}

	@Override
	public void onClick(View v) {
		//请求Android的gallery程序,选取sdcard中的照片
		Intent choosePictureIntent = new Intent(Intent.ACTION_PICK,
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		startActivityForResult(choosePictureIntent, REQUEST_CODE);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {

			brightnessSB.setProgress(100);
			Uri imageFileUri = data.getData();
			Display currentDisplay = getWindowManager().getDefaultDisplay();
			int dw = currentDisplay.getWidth();
			int dh = currentDisplay.getHeight() / 3 - 100;
			try {
				BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
				bmpFactoryOptions.inJustDecodeBounds = true;
				bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);

				int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
						/ (int) dh);
				int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
						/ (int) dw);

				if (heightRatio > 1 && widthRatio > 1) {
					if (heightRatio > widthRatio) {
						bmpFactoryOptions.inSampleSize = heightRatio;
					} else {
						bmpFactoryOptions.inSampleSize = widthRatio;
					}
				}
				bmpFactoryOptions.inJustDecodeBounds = false;
				bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);

				alteredBitmap = Bitmap.createBitmap(bmp.getWidth(),
						bmp.getHeight(), bmp.getConfig());

				canvas = new Canvas(alteredBitmap);
				canvas.drawBitmap(bmp, matrix, paint);

				alteredImageView.setImageBitmap(alteredBitmap);
				chosenImageView.setImageBitmap(bmp);

			} catch (Exception e) {
				Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
			}
		}
	}
}

alt none alt none alt none

git clone https://github.com/lnmcc/brightnessExample.git

ref: 《Android多媒体开发高级编程》