Android多媒体开发
一,音乐播放
二,视频播放
三,歌曲录制
四,相机设置
五,闹钟设置
六,铃声设置
一,音乐播放
1,什么是Open Core?
Open Core是 Android 多媒体框架的核心,所有 Android 平台的音频、视频的采用以及播放等操作,都是通过它来实现。
2,Open Core 的具体功能
A,多媒体文件的播放、下载,包括:3GPP,MPEG-4,AAC 和 MP3 containers。
B,流媒体文件的下载、实时播放,包括:3GPP,HTTP 和 RTSP/RTP。
C,动态视频和静态图像的编码、解码,例如:MPEG-4,H.263 和 AVC (H.264),JPEG。
D,语音编码格式:MP3,AAC,AAC+。
E,视频和图像格式:3GPP,MPEG-4 和 JPEG。
F,视频会议:基于 H324-M 标准。
Open Core是一个多媒体的框架,从宏观上来看,它主要包含了两大方面的内容:
A,PVPPlayer:提供媒体播放器的功能,完成各种音频(Audio)、视频(Video)流的回放(Playback)功能。
B,PVAuthor:提供媒体流记录的功能,完成各种音频、视频流以及静态图像的捕获功能。
3,Mediaplayer 介绍
MediaPlayer 类可以用来播放音频、视频和流媒体,MediaPlayer包含了Audio 和 Video 的播放功能,在 Android 的界面上, Music 和 Video 两个应用程序都是调用 MediaPlayer 实现的。下面两张图是 MediaPlayer 在 Android 和 Open Core 的示例图
下面是图例显示 MediaPlayer 的生命周期
MediaPlayer 常用方法介绍
方法:create(Context context, Uri uri)
解释:静态方法,通过Uri创建一个多媒体播放器。
方法:create(Context context, intresid)
解释:静态方法,通过资源ID创建一个多媒体播放器
方法:create(Context context, Uri uri, SurfaceHolder holder)
解释:静态方法,通过Uri和指定 SurfaceHolder 【抽象类】创建一个多媒体播放器
方法: getCurrentPosition()
解释:返回 Int,得到当前播放位置
方法: getDuration()
解释:返回 Int,得到文件的时间
方法:getVideoHeight()
解释:返回 Int ,得到视频的高度
方法:getVideoWidth()
解释:返回 Int,得到视频的宽度
方法:isLooping()
解释:返回 boolean ,是否循环播放
方法:isPlaying()
解释:返回 boolean,是否正在播放
方法:pause()
解释:无返回值,暂停
方法:prepare()
解释:无返回值,准备同步
方法:prepareAsync()
解释:无返回值,准备异步
方法:release()
解释:无返回值,释放 MediaPlayer 对象
方法:reset()
解释:无返回值,重置 MediaPlayer 对象
方法:seekTo(int msec)
解释:无返回值,指定播放的位置(以毫秒为单位的时间)
方法:setAudioStreamType(intstreamtype)
解释:无返回值,指定流媒体的类型
方法:setDataSource(String path)
解释:无返回值,设置多媒体数据来源【根据路径】
方法:setDataSource(FileDescriptor fd, longoffset, long length)
解释:无返回值,设置多媒体数据来源【根据 FileDescriptor】
方法:setDataSource(FileDescriptor fd)
解释:无返回值,设置多媒体数据来源【根据 FileDescriptor】
方法:setDataSource(Context context, Uri uri)
解释:无返回值,设置多媒体数据来源【根据 Uri】
方法:setDisplay(SurfaceHolder sh)
解释:无返回值,设置用 SurfaceHolder 来显示多媒体
方法:setLooping(booleanlooping)
解释:无返回值,设置是否循环播放
事件:setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListenerlistener)
解释:监听事件,网络流媒体的缓冲监听
事件:setOnCompletionListener(MediaPlayer.OnCompletionListenerlistener)
解释:监听事件,网络流媒体播放结束监听
事件:setOnErrorListener(MediaPlayer.OnErrorListenerlistener)
解释:监听事件,设置错误信息监听
事件:setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListenerlistener)
解释:监听事件,视频尺寸监听
方法:setScreenOnWhilePlaying(booleanscreenOn)
解释:无返回值,设置是否使用 SurfaceHolder 显示
方法:setVolume(floatleftVolume, float rightVolume)
解释:无返回值,设置音量
方法:start()
解释:无返回值,开始播放
方法:stop()
解释:无返回值,停止播放
示例代码
package com.terry;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.app.ListActivity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
public class musicActivity extends ListActivity {
//播放对象
private MediaPlayer myMediaPlayer;
//播放列表
private List<String> myMusicList=new ArrayList<String>();
//当前播放歌曲的索引
private int currentListItem=0;
//音乐的路径
private static final String MUSIC_PATH=new String("/sdcard/");
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myMediaPlayer=new MediaPlayer();
findView();
musicList();
listener();
}
//绑定音乐
void musicList(){
File home=new File(MUSIC_PATH);
if(home.listFiles(new MusicFilter()).length>0){
for(File file:home.listFiles(new MusicFilter())){
myMusicList.add(file.getName());
}
ArrayAdapter<String> musicList=new ArrayAdapter<String>
(musicActivity.this,R.layout.musicitme, myMusicList);
setListAdapter(musicList);
}
}
//获取按钮
void findView(){
viewHolder.start=(Button)findViewById(R.id.start);
viewHolder.stop=(Button)findViewById(R.id.stop);
viewHolder.next=(Button)findViewById(R.id.next);
viewHolder.pause=(Button)findViewById(R.id.pause);
viewHolder.last=(Button)findViewById(R.id.last);
}
//监听事件
void listener(){
//停止
viewHolder.stop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(myMediaPlayer.isPlaying()){
myMediaPlayer.reset();
}
}
});
//开始
viewHolder.start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
playMusic(MUSIC_PATH+myMusicList.get(currentListItem));
}
});
//下一首
viewHolder.next.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
nextMusic();
}
});
//暂停
viewHolder.pause.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(myMediaPlayer.isPlaying()){
myMediaPlayer.pause();
}else{
myMediaPlayer.start();
}
}
});
//上一首
viewHolder.last.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
lastMusic();
}
});
}
//播放音乐
void playMusic(String path){
try {
myMediaPlayer.reset();
myMediaPlayer.setDataSource(path);
myMediaPlayer.prepare();
myMediaPlayer.start();
myMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
nextMusic();
}
});
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
//下一首
void nextMusic(){
if(++currentListItem>=myMusicList.size()){
currentListItem=0;
}
else{
playMusic(MUSIC_PATH+myMusicList.get(currentListItem));
}
}
//上一首
void lastMusic(){
if(currentListItem!=0)
{
if(--currentListItem>=0){
currentListItem=myMusicList.size();
} else{
playMusic(MUSIC_PATH+myMusicList.get(currentListItem));
}
} else{
playMusic(MUSIC_PATH+myMusicList.get(currentListItem));
}
}
//当用户返回时结束音乐并释放音乐对象
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode==KeyEvent.KEYCODE_BACK){
myMediaPlayer.stop();
myMediaPlayer.release();
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
//当选择列表项时播放音乐
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
currentListItem=position;
playMusic(MUSIC_PATH+myMusicList.get(currentListItem));
}
}
运行效果图:
二,视频播放
VideoView类用于播放视频文件,可以从不同的来源(例如资源文件,sdcard或网络)读取图像,计算和维护视频的画面尺寸以使其适用于任何布局管理器,并提供一些诸如缩放、着色之类的显示选项。
VideoView常用方法介绍
public boolean canPause()
解释:判断是否能够暂停播放视频
public boolean canSeekBackward()
解释:判断是否能够倒退
public boolean canSeekForward()
解释:判断是否能够快进
public int getBufferPercentage()
解释:获得缓冲区的百分比
public int getCurrentPosition()
解释:获得当前的位置
public int getDuration()
解释:获得所播放视频的总时间
public boolean isPlaying()
解释:判断是否正在播放视频
public boolean onKeyDown(int keyCode, KeyEventevent)
解释:KeyEvent.Callback.onKeyMultiple()的默认实现。如果视图可用并可按, 当按下 KEYCODE_DPAD_CENTER 或 KEYCODE_ENTER 时执行视图的按下事件。
public boolean onTouchEvent(MotionEventev)
解释:实现该方法来处理触屏事件。
public boolean onTrackballEvent(MotionEventev)
解释:实现这个方法去处理轨迹球的动作事件,轨迹球相对于上次事件移动的位置能用MotionEvent.getX()和 MotionEvent.getY()函数取回。对应用户按下一次方向键,他们通常作为一次移动处理(为了表现来自轨迹球的更小粒度的移动信息,他们返回小数)。
public void pause ()
解释:使得播放暂停
public int resolveAdjustedSize(int desiredSize, int measureSpec)
解释:取得调整后的尺寸。
public void resume ()
解释:恢复挂起的播放器
public void seekTo (intmsec)
解释:设置播放位置
public void setMediaController(MediaControllercontroller)
解释:设置媒体控制器
public void setOnCompletionListener(MediaPlayer.OnCompletionListenerl)
解释:注册在媒体文件播放完毕时调用的回调函数。
public void setOnErrorListener(MediaPlayer.OnErrorListenerl)
解释:注册在设置或播放过程中发生错误时调用的回调函数。如果未指定回调函数, 或回调函数返回假,VideoView 会通知用户发生了错误。
public void setOnPreparedListener(MediaPlayer.OnPreparedListenerl)
解释:注册在媒体文件加载完毕,可以播放时调用的回调函数。
public void setVideoPath(String path)
解释:设置视频文件的路径名
public void setVideoURI(Uri uri)
解释:设置视频文件的统一资源标识符
public void start ()
解释:开始播放视频文件
public void stopPlayback()
解释:停止回放视频文件
public void suspend ()
解释:挂起视频文件的播放
示例代码
1,java代码
public classRemoteVideo extends Activity {
private String path ="";
private String textUrl= "";
private VideoViewmVideoView;
private static int i =0;
privateint width;
privateint heigh;
privateDialog dialog;
privateHandler mHandler = new Handler();
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Bundle bundle =this.getIntent().getExtras();
DisplayMetrics dm = newDisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
width=dm.widthPixels;
heigh=dm.heightPixels;
textUrl =bundle.getString("url");
if(width/heigh>0)
{
setContentView(R.layout.videoview);
path =bundle.getString("widthurl");
Log.i("MP4","heng"+path);
}
if(width/heigh==0)
{
setContentView(R.layout.view);
path =bundle.getString("heighturl");
Log.i("MP4","shu"+path);
}
dialog=ProgressDialog.show(this,"视频加载中...","请您稍候");
mVideoView =(VideoView) findViewById(R.id.surface_view);
mVideoView.setVideoPath(path);
MediaControllercontroller = new MediaController(this);
mVideoView.setMediaController(controller);
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(newOnPreparedListener() {
//@Override
public voidonPrepared(MediaPlayer mp) {
mVideoView.setBackgroundColor(Color.argb(0,0, 255, 0));
dialog.dismiss();
}
});
mVideoView.setOnCompletionListener(newOnCompletionListener() {
//@Override
public voidonCompletion(MediaPlayer mp) {
Toast.makeText(RemoteVideo.this,"video play finished!", Toast.LENGTH_LONG)
.show();
}
});
controller.setOnTouchListener(newView.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
}
@Override
protected voidonResume() {
super.onResume();
mVideoView.seekTo(i);
mVideoView.start();
}
@Override
protected void onStop(){
super.onStop();
mVideoView.pause();
i =mVideoView.getCurrentPosition();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
finish();
return true;
}
return false;
}
}
2,布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
Android:layout_width="fill_parent"android:layout_height="fill_parent"
Android:gravity="left"android:orientation="horizontal">
<VideoView Android:id="@+id/surface_view"
Android:layout_width="176px"android:layout_height="132px"
Android:layout_gravity="left"/>
<WebView Android:id="@+id/web_openonline"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"/>
</LinearLayout>
三,歌曲录制
MediaRecorder在底层是基于OpenCore库实现的,包含了Audio和video的记录功能。
示例代码
1, 清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.Aina.Android" android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Test" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.RECORD_AUDIO">
</uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
</manifest>
2,java代码
package com.Aina.Android;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class Test extends Activity {
/** Called when the activity is first created. */
private ListView mListView = null;
private Button btn_start = null;
private Button btn_stop = null;
private MediaRecorder mMediaRecorder = null;
private List<String> rec = new ArrayList<String>();// 存放录音文件
private File home = null;
private File path = null;
private String temp = "recaudio_";// 临时文件前缀
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mListView = (ListView) this.findViewById(R.id.ListView01);
btn_start = (Button) this.findViewById(R.id.Button01);
btn_stop = (Button) this.findViewById(R.id.Button02);
// 是否存在SD卡
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
home = Environment.getExternalStorageDirectory();
MusicList();
} else {
Toast.makeText(this, "请先插入SD卡", Toast.LENGTH_LONG).show();
return;
}
btn_start.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
try {
// 创建录音临时文件
path = File.createTempFile(temp, ".amr", home);
setTitle("=="+path.getAbsolutePath());
mMediaRecorder = new MediaRecorder();
mMediaRecorder
.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置数据来源,麦克风
mMediaRecorder
.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);// 设置格式
mMediaRecorder
.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);// 设置编码
mMediaRecorder.setOutputFile(path.getAbsolutePath());// 设置输出文件路径
mMediaRecorder.prepare();
mMediaRecorder.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
btn_stop.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder = null;
MusicList();
}
});
mListView.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
String path = home+File.separator+rec.get(arg2);
File f = new File(path);
PlayMusic(f);
}
});
}
/**
* 显示列表
*/
public void MusicList() {
File[] f = home.listFiles(new MusicFilter());
rec.clear();
for (int i = 0; i < f.length; i++) {
File file = f[i];
rec.add(file.getName());
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, rec);
mListView.setAdapter(adapter);
}
/**
* 播放录音文件
* @param file
*/
public void PlayMusic(File file){
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "audio");
this.startActivity(intent);
}
class MusicFilter implements FilenameFilter {
public boolean accept(File dir, String filename) {
// TODO Auto-generated method stub
return (filename.endsWith(".amr"));
}
}
}
四,相机设置
通过android.hardware.Camera类来控制摄像头设备,通过Camera类可以与摄像头服务取得(断开)链接、可以设置摄像头的各种属性、开始(结束)图像预览、拍照或则录像。要使用Camera只有通过调用Camera的open()函数来得到一个Camera对象。另外系统还提供了一些接口来控制Camera的状态:
- android.hardware.Camera.AutoFocusCallback :当摄像头自动对焦的时候调用,该接口具有一个函数 void onAutoFocus(boolean success, Camera camera);当自动对焦成功的时候success参数的值为true,否则为false。
- android.hardware.Camera.ErrorCallback :当摄像头出错的时候调用,该接口具有一个函数 void onError(int error, Camera camera); 参数error为错误类型,其取值为Camera类中的常量CAMERA_ERROR_UNKNOWN或CAMERA_ERROR_SERVER_DIED;前者表明错误类型不明确,后者表明服务已关闭,在这种情况下必须释放当前的Camera对象然后重新初始化一个。
- android.hardware.Camera.PreviewCallback :在图像预览时候调用,该接口具有一个函数void onPreviewFrame(byte[] data, Camera camera); 参数data为每帧图像的数据流。
- android.hardware.Camera.ShutterCallback :当摄像头快门关闭的时候调用,该接口具有一个函数void onShutter(); 可以在该函数中通知用户快门已关闭,例如播放一个声音。
- android.hardware.Camera.PictureCallback :当拍摄照片的时候调用,该接口具有一个函数void onPictureTaken(byte[] data, Camera camera); 参数data为拍摄照片的数据流。
当取得照片的数据流后可以通过BitmapFactory的decodeByteArray() 函数来解析图片。
另外还可以通过Camera对象的getParameters()函数得到一个android.hardware.Camera.Parameters对象,Parameters提供了一些接口来设置Camera的属性:
- setPictureFormat(int pixel_format):设置图片的格式,其取值为PixelFormat.YCbCr_420_SP、PixelFormat.RGB_565或则PixelFormat.JPEG。
- setPreviewFormat(int pixel_format):设置图片预览的格式,取值同上。
- setPictureSize(int width, int height):设置图片的高度和宽度,单位为像素。
- setPreviewSize(int width, int height):设置图片预览的高度和宽度,取值同上。
- setPreviewFrameRate(int fps):设置图片预览的帧速。
在设置好Camera的参数后,可以通过函数voidstartPreview()开始预览图像、void stopPreview()结束预览,通过autoFocus(AutoFocusCallbackcb)来自动对焦,最后可以通过takePicture(ShutterCallback shutter,PictureCallback raw, PictureCallback jpeg)函数来拍照。该函数有三个参数,分别为快门回调接口、原生图像数据接口和压缩格式图片数据接口。如果数据格式不存在的话数据流为空,如果不需要实现这些接口则这些参数取值可以为null。
以上就是关于Camera的基础知识和相关的API介绍,下面来具体看看如何在程序中拍照并使用照片。
示例代码
import java.io.File;
import java.io.FileOutputStream;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.graphics.Bitmap.CompressFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
public class MyCamera extends Activity{
private SurfaceView surfaceView;
Camera camera;
boolean preview=false;
private static final String TAG = "camera";
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Window window=getWindow();
// 设置没有title
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 全屏显示
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager
.LayoutParams.FLAG_FULLSCREEN);
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.main);
surfaceView=(SurfaceView)this.findViewById(R.id.surfaceView);
surfaceView.getHolder().addCallback(new SufaceListener());
//下面设置surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.getHolder().setFixedSize(176,144);//设置分辨率
}
private final class SufaceListener implements SurfaceHolder.Callback{
public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){
}
public void surfaceCreated(SurfaceHolder holder){
try{
camera=Camera.open();
Camera.Parameters parameters=camera.getParameters();
WindowManager wm=(WindowManager)getSystemService(Context.WINDOW_SERVICE);
Display display=wm.getDefaultDisplay();
parameters.setPreviewSize(display.getWidth(),display.getHeight());
//每秒3帧
parameters.setPreviewFrameRate(3);
parameters.setPreviewFormat(PixelFormat.JPEG);
parameters.set("jpeg-quality", 85);
parameters.setPictureSize(display.getWidth(), display.getHeight());
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceView.getHolder());//显示取景画面
camera.startPreview();
preview=true;
}
catch(Exception e){
Log.e(TAG,e.toString());
}
}
public void surfaceDestroyed(SurfaceHolder holder){
if(camera!=null){
if(preview)
camera.stopPreview();
camera.release();
camera=null;
}
}
}
public boolean onKeyDown(int keyCode,KeyEvent event){
if(camera!=null&&event.getRepeatCount()==0){
switch(keyCode){
case KeyEvent.KEYCODE_SEARCH:
camera.autoFocus(null);//自动对焦
break;
case KeyEvent.KEYCODE_DPAD_CENTER: ;
case KeyEvent.KEYCODE_CAMERA:
camera.takePicture(null,null, new PictureCallbackListener());
break;
}
}
return true;
}
public final class PictureCallbackListener implements Camera.PictureCallback{
public void onPictureTaken(byte[] data,Camera canera){
try{
Bitmap bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);
File file=new File(Environment.getExternalStorageDirectory(),"ljh.jpg");
FileOutputStream outStream=new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 100,outStream);
outStream.close();
//
camera.stopPreview();
camera.startPreview();
preview=true;
}
catch(Exception e){
Log.e(TAG,e.toString());
}
}
}
}
五,闹钟设置
在Android中,通过AlarmManager类来实现闹钟的。
常用方法 :
void cancel(PendingIntent operation)
解释: 取消已经注册的与参数匹配的闹铃
void set(int type, long triggerAtTime, PendingIntent operation)
解释:注册一个新的闹铃
void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation)
解释:注册一个重复类型的闹铃
void setTimeZone(String timeZone)
解释:设置时区
示例代码
1,java代码:AlamrReceiver
package com.Aina.Android;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AlamrReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "闹钟时间到", Toast.LENGTH_LONG).show();
}
}
2,java代码:Test
package com.Aina.Android;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
public class Test extends Activity {
/** Called when the activity is first created. */
private TextView tv = null;
private Button btn_set = null;
private Button btn_cel = null;
private Calendar c = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) this.findViewById(R.id.TextView);
btn_set = (Button) this.findViewById(R.id.Button01);
btn_cel = (Button) this.findViewById(R.id.Button02);
c = Calendar.getInstance();
btn_set.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
c.setTimeInMillis(System.currentTimeMillis());
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
new TimePickerDialog(Test.this,new TimePickerDialog.OnTimeSetListener(){
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
// TODO Auto-generated method stub
c.setTimeInMillis(System.currentTimeMillis());
c.set(Calendar.HOUR_OF_DAY, hourOfDay);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
Intent intent = new Intent(Test.this,AlamrReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(Test.this, 0, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);//设置闹钟
am.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), (10*1000), pi);//重复设置
tv.setText("设置的闹钟时间为:"+hourOfDay+":"+minute);
}
},hour,minute,true).show();
}
});
btn_cel.setOnClickListener(new Button.OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(Test.this,AlamrReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(Test.this, 0, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
am.cancel(pi);
tv.setText("闹钟取消");
}
});
}
}
3,布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:id="@+id/TextView"
android:layout_height="wrap_content" android:text="@string/hello" />
<Button android:text="设置闹钟" android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<Button android:text="取消闹钟" android:id="@+id/Button02"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
4,清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.Aina.Android"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Test"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlamrReceiver" android:process=":remote"></receiver>
</application>
</manifest>
六,铃声设置
Android提供了RingtoneManager类来专门操作各种铃声。
常用方法:
getActualDefaultRingtoneUri(Context context, int type)
解释:取得当前默认钤声的Uri
解释:返回所有可用钤声的游标
getDefaultType(Uri defaultRingtoneUri)
解释:得到指定Uri的默认铃声类型
getDefaultUri(int type)
解释:得到指定铃声类型的默认Uri
setActualDefaultRingtoneUri(Context context, int type, Uri ringtoneUri)
解释:设置默认铃声
示例代码:
1, 布局文件
< ?xmlversion="1.0" encoding="utf-8"?>
<linearlayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<textviewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<buttonandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn1"
android:id="@+id/btn1"
/>
<buttonandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn2"
android:id="@+id/btn2"
/>
<buttonandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/btn3"
android:id="@+id/btn3"
/>
</linearlayout>
2, java代码
packagenet.androidla.ringtonemanager;
import java.io.File;
importandroid.app.Activity;
importandroid.content.Intent;
importandroid.media.RingtoneManager;
import android.net.Uri;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
public classRingtoneManagerActivity extends Activity {
privateButton btn1 = null;
privateButton btn2 = null;
privateButton btn3 = null;
privatestatic final int ringtone = 0;
privatestatic final int alarm = 1;
privatestatic final int notification =2;
privatestatic final String fileRingtone = Environment.getExternalStorageDirectory() +"/music/ringtones";
privatestatic final String fileAlarm = Environment.getExternalStorageDirectory() +"/music/alarms";
privatestatic final String fileNotification =Environment.getExternalStorageDirectory() + "/music/notifications";
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn1= (Button) findViewById(R.id.btn1);
btn1.setOnClickListener(onClickListener);
btn2= (Button) findViewById(R.id.btn2);
btn2.setOnClickListener(onClickListener);
btn3= (Button) findViewById(R.id.btn3);
btn3.setOnClickListener(onClickListener);
}
privateOnClickListener onClickListener = new OnClickListener() {
@Override
publicvoid onClick(View v) {
Buttonbtn = (Button) v;
switch(btn.getId()) {
caseR.id.btn1:
if(isFile(fileRingtone)) {
Intentintent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,RingtoneManager.TYPE_RINGTONE);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,R.string.btn1);
startActivityForResult(intent,ringtone);
}
break;
caseR.id.btn2:
if(isFile(fileAlarm)) {
Intentintent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,RingtoneManager.TYPE_ALARM);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,R.string.btn2);
startActivityForResult(intent,alarm);
}
break;
caseR.id.btn3:
if(isFile(fileNotification)) {
Intentintent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,RingtoneManager.TYPE_NOTIFICATION);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE,R.string.btn3);
startActivityForResult(intent,notification);
}
break;
}
}
};
@Override
protectedvoid onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode, data);
if(resultCode != RESULT_OK) {
return;
}else {
Uriuri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if(uri != null) {
switch(requestCode) {
caseringtone:
RingtoneManager.setActualDefaultRingtoneUri(this,RingtoneManager.TYPE_RINGTONE, uri);
break;
casealarm:
RingtoneManager.setActualDefaultRingtoneUri(this,RingtoneManager.TYPE_ALARM, uri);
break;
casenotification:
RingtoneManager.setActualDefaultRingtoneUri(this,RingtoneManager.TYPE_NOTIFICATION, uri);
break;
}
}
}
}
privateboolean isFile(String path) {
booleanflag = false;
Filef = new File(path);
if(f.exists()) {
flag= true;
}else {
if(f.mkdirs()) {
flag= true;
}else {
flag= false;
}
}
returnflag;
}
}
3, 在AndroidManifest.xml中注册相关权限
< ?xmlversion="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="net.androidla.ringtonemanager"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<!--访问网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!--向SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--在SDCard上创建删除文件目录权限 -->
<uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!--在SDCard上写入系统配置的权限 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
<activityandroid:name=".RingtoneManagerActivity"
android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent>
</activity>
</application>
</manifest>
本文来自上海Android培训官方网站,感谢上海it培训机构推荐。