Android开发学习之以CameraAPI方式实现相机功能(一)——快速实现相机

今天无意当中发现在Android开发学习之基于ZBar实现微信扫一扫中的一部分代码可以用来以硬件方式实现一个照相机的功能,在Android开发学习之调用系统相机完成拍照的实现中我们是以Intent方式调用系统内置的相机来完成拍照的,今天呢,就让我们来以Camera类为核心来开发自己的相机应用吧。在Android的官方文档中,以硬件方式定制相机应用的步骤如下:


1. 检查和访问Camera

创建代码来检查Camera和所申请访问的存在性;

2. 创建一个预览类

继承SurfaceView来创建一个Camera的预览类,并实现SurfaceHolder接口。这个类用来预览来自Camera的实施图像。

3. 构建一个预览布局

一旦有了Camera预览类,就可以把这个预览类和你想要的用户界面控制结合在一起来创建一个视图布局。

4. 针对采集建立监听

把监听器与响应用户动作(如按下按钮)的界面控制连接到一起来启动图像或视频的采集。

5. 采集和保存文件

针对真正采集的图片或视频,以及输出的保存来编写代码。

6. 释放Camera

使用Camera之后,你的应用程序必须释放Camera,以便其他应用程序能够使用。

Camera硬件是一个必须要认真管理的共享资源,因此你的应用程序在使用它时,不能跟其他应用程序发生冲突。下文将讨论如何检查Camera硬件、如何申请对Camera的访问,如何采集图片和视频,以及在应用使用完成后如何释放Camera。

警告:在应用程序使用完Camera时,要记住通过调用Camera.release()方法来释放Camera对象。如果你的应用程序没有正确的释放Camera,所有的后续的视图对Camera的访问,包括你自己的应用程序,都会失败,并可能到你的或其他的应用程序关闭。

下面我们就来按照上面的步骤来一步步的制作一个属于自己的相机应用吧!

第一步:检查和访问相机

/** 官方建议的安全地访问摄像头的方法  **/
	public static Camera getCameraInstance(){ 
	    Camera c = null; 
	    try { 
	        c = Camera.open();
	    } 
	    catch (Exception e){
	    Log.d("TAG", "Error is "+e.getMessage());
	    } 
	    return c;
	}
	
	/** 检查设备是否支持摄像头  **/
	private boolean CheckCameraHardware(Context mContext)
	{
		if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
		{ 
	        // 摄像头存在 
	        return true; 
	    } else { 
	        // 摄像头不存在 
	        return false; 
	    } 
	}
	

第二步:创建一个预览类。这里我们使用的是官方API中提供的一个基本的预览类:

package com.android.OpenCamera;

import java.io.IOException;

import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/** 一个基本的相机预览界面类    **/
@SuppressLint("ViewConstructor")
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

	/** Camera **/
	private Camera mCamera;
	/** SurfaceHolder **/
	private SurfaceHolder mHolder;
	
	/** CamreaPreview构造函数   **/
	@SuppressWarnings("deprecation")
	public CameraPreview(Context mContext,Camera mCamera) 
	{
		super(mContext);
		this.mCamera=mCamera;
        // 安装一个SurfaceHolder.Callback,
        // 这样创建和销毁底层surface时能够获得通知。
        mHolder = getHolder(); 
        mHolder.addCallback(this); 
        // 已过期的设置,但版本低于3.0的Android还需要
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
	}

	@Override
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) 
	{
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) 
	{
	   try {
		mCamera.setPreviewDisplay(holder);
		mCamera.startPreview();
		mCamera.setDisplayOrientation(90);
	   } catch (IOException e) {
		Log.d("TAG", "Error is "+e.getMessage());
	   }	
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) 
	{
		// 如果预览无法更改或旋转,注意此处的事件
        // 确保在缩放或重排时停止预览
        if (mHolder.getSurface() == null){ 
          // 预览surface不存在
          return; 
        } 
        // 更改时停止预览 
        try { 
            mCamera.stopPreview(); 
        } catch (Exception e){ 
          // 忽略:试图停止不存在的预览
        } 
        // 在此进行缩放、旋转和重新组织格式
        // 以新的设置启动预
        try { 
            mCamera.setPreviewDisplay(mHolder); 
            mCamera.setDisplayOrientation(90); 
            mCamera.startPreview(); 
        } catch (Exception e){ 
            Log.d("TAG", "Error is " + e.getMessage()); 
        } 
		
	}

}

第三步:构建预览布局。这里我们使用FrameLayout来加载第二步创建的预览类,使用一个按钮进行拍照并完成储存,使用一个ImageView显示拍照的缩略图,当我们点击这个缩略图时时,系统将会调用相应的程序来打开这个图片。

<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" >
    <FrameLayout
        android:id="@+id/PreviewView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.8" >
    </FrameLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.2"
        android:background="@drawable/main_bg">
        <Button
            android:id="@+id/BtnCapture"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:background="@drawable/camera"/>
        <ImageView
            android:id="@+id/ThumbsView"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_margin="15dp"
            android:contentDescription="@string/Description" />
    </RelativeLayout>
</LinearLayout>

第四步:针对采集监听。其中PictureCallback接口用于处理拍照的结果,这里我们做三件事情,第一,保存图片;第二,显示缩略图;第三、保存当前图片的Uri,以便于系统的访问。ShutterCallback接口用于处理按下快门的事件,这里我们使用MediaPlayer类来播放快门按下时的音效。

/** 拍照回调接口  **/
	private PictureCallback mPicureCallback=new PictureCallback()
	{
		@Override
		public void onPictureTaken(byte[] mData, Camera camera) 
		{
			File mPictureFile = StorageHelper.getOutputFile(StorageHelper.MEDIA_TYPE_IMAGE); 
	        if (mPictureFile == null){  
	            return; 
	        }
	        try { 
	        	/** 存储照片  **/
	            FileOutputStream fos = new FileOutputStream(mPictureFile); 
	            fos.write(mData); 
	            fos.close(); 
	            /** 设置缩略图  **/
	            Bitmap mBitmap=BitmapFactory.decodeByteArray(mData, 0, mData.length);
	            ThumbsView.setImageBitmap(mBitmap);
	            /** 获取缩略图Uri  **/
	            mUri=StorageHelper.getOutputUri(mPictureFile);
	            /**停止预览**/
	            mCamera.stopPreview();
	            /**开始预览**/
	            mCamera.startPreview();
	        } catch (FileNotFoundException e) { 
	        	e.printStackTrace();
	        } catch (IOException e) {
				e.printStackTrace();
			}
		}
	};
	
/** 快门回调接口  **/
    private ShutterCallback mShutterCallback=new ShutterCallback()
    {
		@Override
		public void onShutter() 
		{
			mPlayer=new MediaPlayer();
			mPlayer=MediaPlayer.create(MainActivity.this,R.raw.shutter);
			try {
				mPlayer.prepare();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			mPlayer.start();
		}
    };

第五步:采集与保存。采集与保存在第四步已经给出了,这里给出一个用于保存文件的辅助类StorageHelper类:

package com.android.OpenCamera;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.net.Uri;
import android.os.Environment;

@SuppressLint("SimpleDateFormat")
public final class StorageHelper 
{
   public static final int MEDIA_TYPE_IMAGE=0;
   public static final int MEDIA_TYPE_VIDEO=1;
   
   public static Uri  getOutputUri(File mFile)
   {
	   return Uri.fromFile(mFile);
   }
   
   
   public static File getOutputFile(int mType)
   {
	   File mMediaFileDir=new File(Environment.getExternalStorageDirectory(),"OpenCamera");
	   if(!mMediaFileDir.exists())
	   {
		   if(!mMediaFileDir.mkdir())
			{
			   return null;
			}
	   }
	   File mMediaFile=null;
	   /**  创建文件名   **/
	   String mFileName=new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
	   switch(mType)
	   {
	     case MEDIA_TYPE_IMAGE:
	    	 mMediaFile=new File(mMediaFileDir.getPath()+File.separator+"IMG_"+mFileName+".jpg");
	    	 break;
	     case MEDIA_TYPE_VIDEO:
	    	 mMediaFile=new File(mMediaFileDir.getPath()+File.separator+"VID_"+mFileName+".mp4");
	    	 break; 
	    	 default:
	    		 mMediaFile=null;
	   }
	   return mMediaFile;
   }
}

第六步:相机的释放

if (mCamera != null){ 
            mCamera.release();
            mCamera = null; 
        } 

通过以上步骤,我们就完成了一个简单的相机,最后给出主要的逻辑代码:

package com.android.OpenCamera;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

	
	/** 相机   **/
	private Camera mCamera;  
	/** 预览界面  **/
	private CameraPreview mPreview;
	/** 缩略图  **/
	ImageView ThumbsView;
	/** 当前缩略图Uri **/
	private Uri mUri;
	/** MediaPlayer **/
	private MediaPlayer mPlayer;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		/** 隐藏标题栏  **/
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		/** 隐藏状态栏  **/
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        /** 禁用锁屏,因为再次唤醒屏幕程序就会终止,暂时不知道怎么解决  **/
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		setContentView(R.layout.activity_main);
		
		/** 硬件检查  **/
		if(CheckCameraHardware(this)==false)
		{
			Toast.makeText(this, "很抱歉,您的设备可能不支持摄像头功能!", Toast.LENGTH_SHORT).show();
			return;
		}
		
		/** 获取相机  **/
		mCamera=getCameraInstance();
		/** 获取预览界面   **/
        mPreview = new CameraPreview(this, mCamera); 
        FrameLayout mFrameLayout = (FrameLayout)findViewById(R.id.PreviewView); 
        mFrameLayout.addView(mPreview); 
        mCamera.startPreview();
        /** 拍照按钮  **/
        Button BtnCapture = (Button) findViewById(R.id.BtnCapture);
        BtnCapture.setOnClickListener(new OnClickListener()
        {
			@Override
			public void onClick(View v) 
			{
				/** 使用takePicture()方法完成拍照  **/
				mCamera.autoFocus(new AutoFocusCallback()
				{
					/** 自动聚焦聚焦后完成拍照  **/
					@Override
					public void onAutoFocus(boolean isSuccess, Camera camera) 
					{
						if(isSuccess&&camera!=null)
						{
							mCamera.takePicture(mShutterCallback, null, mPicureCallback);
						}
					}
					
				});
			}
        });
        
        /** 相机缩略图  **/
        
        ThumbsView = (ImageView)findViewById(R.id.ThumbsView);
        ThumbsView.setOnClickListener(new OnClickListener()
        {
			@Override
			public void onClick(View v) 
			{
				/** 使用Uri访问当前缩略图  **/
				Intent intent = new Intent(Intent.ACTION_VIEW); 
			    intent.setDataAndType(mUri, "image/*");
			    startActivity(intent);
			}
        });
	}
	/** 快门回调接口  **/
    private ShutterCallback mShutterCallback=new ShutterCallback()
    {
		@Override
		public void onShutter() 
		{
			mPlayer=new MediaPlayer();
			mPlayer=MediaPlayer.create(MainActivity.this,R.raw.shutter);
			try {
				mPlayer.prepare();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			mPlayer.start();
		}
    };
    
	/** 拍照回调接口  **/
	private PictureCallback mPicureCallback=new PictureCallback()
	{
		@Override
		public void onPictureTaken(byte[] mData, Camera camera) 
		{
			File mPictureFile = StorageHelper.getOutputFile(StorageHelper.MEDIA_TYPE_IMAGE); 
	        if (mPictureFile == null){  
	            return; 
	        }
	        try { 
	        	/** 存储照片  **/
	            FileOutputStream fos = new FileOutputStream(mPictureFile); 
	            fos.write(mData); 
	            fos.close(); 
	            /** 设置缩略图  **/
	            Bitmap mBitmap=BitmapFactory.decodeByteArray(mData, 0, mData.length);
	            ThumbsView.setImageBitmap(mBitmap);
	            /** 获取缩略图Uri  **/
	            mUri=StorageHelper.getOutputUri(mPictureFile);
	            /**停止预览**/
	            mCamera.stopPreview();
	            /**开始预览**/
	            mCamera.startPreview();
	        } catch (FileNotFoundException e) { 
	        	e.printStackTrace();
	        } catch (IOException e) {
				e.printStackTrace();
			}
		}
	};
	
	
	/** 官方建议的安全地访问摄像头的方法  **/
	public static Camera getCameraInstance(){ 
	    Camera c = null; 
	    try { 
	        c = Camera.open();
	    } 
	    catch (Exception e){
	    Log.d("TAG", "Error is "+e.getMessage());
	    } 
	    return c;
	}
	
	/** 检查设备是否支持摄像头  **/
	private boolean CheckCameraHardware(Context mContext)
	{
		if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
		{ 
	        // 摄像头存在 
	        return true; 
	    } else { 
	        // 摄像头不存在 
	        return false; 
	    } 
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		if (mCamera != null){ 
            mCamera.release();
            mCamera = null; 
        } 
	}

	@Override
	protected void onResume() 
	{
		super.onResume();
		if(mCamera == null)
        {
            mCamera = getCameraInstance();
            mCamera.startPreview(); 	
        }
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

这里一直有一个困惑我的问题,就是当手机锁屏以后再次唤醒屏幕,程序会立即终止。因为找不到原因,所以目前只能用代码控制设备禁止锁屏来避免这个问题的发生。这个问题和 Android开发学习之基于ZBar实现微信扫一扫是一样的,留给大家去思考了。记得给程序加入以下权限:

<uses-permission android:name="android.permission.CAMERA" />
        <uses-feature android:name="android.hardware.camera" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

晚上看到Camera360开放了SDK的消息。主推拍照和滤镜API,其实开源的滤镜有很多啦,结合我们今天的例子,我们完全可以做出一个不错的相机应用来,作为长期受益于开源社区的回报,我决定在整合滤镜以后把全部的程序开源,希望大家支持我哦。唉,明天要考试了,我竟然还能如此充满激情的编程,其实这就是编程的魅力啦,在编程的世界里,我可以完全按照自己的意愿去做自己喜欢的,而这就够了,当老师和同学们都觉得我在抱怨专业课的时候,其实我只是想让自己的内心感到快乐而已。好了,晚安,各位!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(HelloAndroid!) 2.3 Android应用程序架构——从此开始 2.4 可视化的界面开发工具 2.5 部署应用程序到Android手机 第3章 用户人机界面 3.1 更改与显示文字标签——TextView标签的使用 3.2 更改手机窗口画面底色——drawable定义颜色常数的方法 3.3 更改TextView文字颜色——引用Drawable颜色常数及背景色 3.4 置换TextView文字——CharSequence数据类型与ResourceID应用 3.5 取得手机屏幕大小——DisplayMetrics取得画面宽高的方法 3.6 样式化的定型对象——Style样式的定义 3.7 简易的按钮事件——Button事件处理 3.8 手机页面的转换——setContentView的应用 3.9 调用另一个Activity——Intent对象的使用 3.10 不同Activity之间的数据传递——Bundle对象的实现 3.11 返回数据到前一个Activity——startActivityForResult方法 3.12 具有交互功能的对话框——AlertDialog窗口 3.13 置换文字颜色的机关——Button与TextView的交互 3.14 控制不同的文字字体——Typeface对象使用 3.15 如iPhone拖动相片特效——Gallery画廊 3.16 自制计算器——多按钮的整合应用 3.17 关于(About)程序信息——Menu功能菜单程序设计 3.18 程序加载,请稍后——ProgressDialog与线程整合应用 3.19 全屏幕以按钮覆盖——动态产生按钮并最大化 3.20 今晚到哪儿打牙祭?——具选择功能的对话框 3.21 Android变脸——主题(Theme)实现 第4章 史上超豪华的手机控件 4.1 EditText与TextView共舞——setOnKeyListener事件 4.2 设计具有背景图的按钮——ImageButton的焦点及事件处理 4.3 给耶诞老人的信息——Toast对象的使用 4.4 我同意条款——CheckBox的isChecked属性 4.5 消费券采购列表——多选项CheckBox的应用 4.6 向左或向右——RadioGroup组与onCheckedChanged事件 4.7 专业相框设计——ImageView的堆栈应用 4.8 自定义下拉菜单模式——Spinner与setDropDownViewResource 4.9 动态添加/删除的Spinner菜单——ArrayList与Widget的依赖性 4.10 心爱小宝贝相片集——Gallery与衍生BaseAdapter容器 4.11 快速的搜索手机文件引擎——JavaI/O的应用 4.12 按钮也能随点击变换——ImageButton选择特效 4.13 具自动提示功能的菜单——AutoCompleteTextView与数组 4.14 数字及模拟小时钟设计——AnalogClock与DigitalClock的原理 4.15 动态输入日期与时间——DatePicker与TimePicker应用 4.16 猜猜红心A在那儿——ImageView点击事件与透明度处理 4.17 后台程序运行进度提示——ProgressBar与Handler的整合应用 4.18 动态文字排版——GridView与ArrayAdapter设计 4.19 在Activity里显示列表列表——ListView的布局 4.20 以动态列表配置选项——ListActivity与Menu整合技巧 4.21 查找程序根目录下所有文件——JavaI/O与ListActivity的结合.. 4.22 加载手机磁盘里的图文件——使用decodeFile方法 4.23 动态放大缩小ImageView里的图片——运用Matrix对象来缩放图文件 4.24 动态旋转图片——Bitmap与Matrix旋转ImageView 4.25 猜猜我在想什么——RadioButtonID 4.26 离开与关闭程序的弹出窗口——对话窗口上的ICON图标 第5章 交互式通信服务与手机控制 5.1 具有正则表达式的TextView——Linkify规则 5.2 ACTION!CALL!拨打电话——Intent.ACTION.CALL的使用 5.3 自制发送短信程序——SmsManager与PendingIntent对象 5.4 自制发送Email程序——Intent在Email上的使用 5.5 自制日历手机数据库——实现SQLiteOpenHelper 5.6 手机震动的节奏——Vibrator对象及周期运用 5.7 图文可视化提醒——Toast与LinearLayoutView 5.8 状态栏的图标与文字提醒——NotificationManager与Notification对象的应用 5.9 搜索手机通讯录自动完成——使用ContentResolver 5.10 取得联系人资料——Provider.Contact的使用 5.11 制作有图标的文件资源管理器——自定义Adapter对象 5.12 还原手机默认桌面——重写clearWallpaper方法 5.13 置换手机背景图——Gallery与setWallpaper整合实现 5.14 撷取手机现存桌面——getWallpaper与setImageDrawable 5.15 文件资源管理器再进化——JavaI/O修改文件名及删除 5.16 取得目前File与Cache的路径——getCacheDir与getFilesDir 5.17 打开/关闭WiFi服务——WifiManager状态判断 5.18 取得SIM卡内的信息——TelephonyManager的应用 5.19 调用拨号按钮——打电话CALL_BUTTON 5.20 DPAD按键处理——onKeyDown事件与Layout坐标交互 5.21 任务管理器正在运行的程序——RunningTaskInfo 5.22 动态更改屏幕方向——LANDSCAPE与PORTRAIT 5.23 系统设置更改事件——onConfigurationChanged信息处理 5.24 取得电信网络与手机相关信息——TelephonyManager与android.provider.Settings.System的应用 第6章 手机自动服务纪实 6.1 您有一条短信popup提醒——常驻BroadcastReceiver的应用 6.2 手机电池计量还剩多少——使用BroadcastReceiver捕捉Intent.ACTION_BATTERY_CHANGED 6.3 群发拜年短信给联系人——ACTION_PICK与Uri对象 6.4 开始与停止系统服务——Service与Runnable整合并用 6.5 通过短信发送email通知——BroadcastReceiver与Intent整合 6.6 手机拨接状态——PhoneStateListener之onCallStateChanged 6.7 有来电,发送邮件通知——PhoneStateListener与ACTION_SEND 6.8 存储卡剩余多少容量——Environment加StatFs 6.9 访问本机内存与存储卡——File的创建与删除 6.10 实现可定时响起的闹钟——PendingIntent与AlarmManager的运用 6.11 黑名单来电自动静音——PhoneStateListener与AudioManager 6.12 手机翻背面即静音震动——SensorListener及AudioManager整合应用 6.13 指定时间置换桌面背景——多AlarmManager事件处理 6.14 判断发送短信后的状态——BroadcastReceiver聆听PendingIntent 6.15 后台服务送出广播信息——sendBroadcast与BroadcastReceiver 6.16 开机程序设计——receiver与intent-filter协同作业 6.17 双向短信常驻服务——Service与receiver实例 第7章 娱乐多媒体 7.1 访问Drawable资源的宽高——ContextMenu与Bitmap的应用 7.2 绘制几何图形——使用android.graphics类 7.3 手机屏幕保护程序——FadeIn/FadeOut特效与运行线程 7.4 用手指移动画面里的照片——onTouchEvent事件判断 7.5 加载存储卡的Gallery相簿——FileArrayList 7.6 取得手机内置媒体里的图文件——ACTION_GET_CONTENT取回InputStream 7.7 相片导航向导与设置背景桌面——ImageSwitcher与Gallery 7.8 调整音量大小声——AudioManager控制音量 7.9 播放mp3资源文件——raw文件夹与MediaPlayer的使用 7.10 播放存储卡里的mp3音乐——MediaPlayer.setDataSource 7.11 自制录音/播放录音程序——MediaRecorder与AudioEncoder 7.12 通过收到短信开始秘密录音——MediaRecorder与BroadcastReceiver实例 7.13 内置影片播放器载入3gp电影——VideoViewWidget 7.14 自制3gp影片播放器——MediaPlayer与实现SurfaceView 7.15 相机预览及拍照临时文件——Camera及PictureCallback事件 第8章 当Android与Internet接轨 8.1 HTTPGET/POST传递参数——HTTP连接示范 8.2 在程序里浏览网页——WebView.loadUrl 8.3 嵌入HTML标记的程序——WebView.loadData 8.4 设计前往打开网页功能——Intent与Uri.parse 8.5 将网络图像网址放入Gallery显示——URL.URLConnection.BaseAdapter 8.6 即时访问网络图文件展示——HttpURLConnection 8.7 手机气象局,实时卫星云图——HttpURLConnection与URLConnection和运行线程 8.8 通过网络播放MP3——Runnable存储FileOutputStream技巧 8.9 设置远程下载音乐为手机铃声——RingtoneManager与铃声存放路径 8.10 远程下载桌面背景图案——URLConnection与setWallpaper()搭配 8.11 将手机文件上传至网站服务器——模拟HTTPFORM的POSTACTION 8.12 移动博客发布器——以XML-RPC达成远程过程调用 8.13 移动RSS阅读器——利用SAXParser解析XML 8.14 远程下载安装Android程序——APKInstaller的应用 8.15 手机下载看3gp影片——Runnable混搭SurfaceView 8.16 访问网站LoginAPI——远程服务器验证程序运行权限 8.17 地震速报!——HttpURLConnection与Service侦测服务 第9章 Google服务与Android混搭 9.1 Google帐号验证Token——AuthSub 9.2 Google搜索——AutoCompleteTextView与GoogleSearchAPI 9.3 前端产生QRCode二维条形码——GoogleChartAPI 9.4 以经纬度查找目的地位置——GeoPoint与MapView的搭配运用 9.5 GPSGoogle地图——LocationListener与MapView实时更新 9.6 移动版GoogleMap——Geocoder反查Address对象 9.7 规划导航路径——DirectionsRoute 9.8 移动设备上的Picasa相册——GooglePicasaAPI 9.9 随身翻译机——GoogleTranslateAPI 第10章 创意Android程序设计 10.1 手机手电筒——PowerManager控制WakeLock并改变手机亮度 10.2 GPS轨迹记录器——利用LocationListener在地图上画图并换算距离 10.3 女性贴身看护——AlarmManager.DatePicker.TimePicker 10.4 手机QRCode二维条形码生成器——Canvas与SurfaceHolder绘图 10.5 AndroidQRCode二维条形码扫描仪——BitmapFactory.decodeByteArray 10.6 上班族今天午要吃什么——热量骰子地图 10.7 掷杯筊——把手机放在空甩事件处理...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值