Android的Camera包含取景(preview)和拍摄照片(take picture)的功能。其实Camera的功能还是比较简单,只是需要注意其架构分成客户端和服务器两个部分,它们建立在Android的进程间通讯Binder的结构上。
Rexsee的扩展中除了对于Camera的支持,同时还可结合外部的一些开源代码实现对照片的快速处理,可以实现类似于美图秀秀、Camera360等的效果。。关于一些具体的应用Demo可以在Rexsee项目中心查阅:
http://www.rexsee.com/project/index.php
【函数】
void takePicture()
【函数】
void takePicture(int quality)
【说明】
拍摄照片。拍摄成功触发事件onTakePictureSuccessed,失败则触发onTakePictureFailed。
【返回】
无
【参数】
quality:0表示较低质量,1表示较高质量,为方便上传,默认为0。
【示例】
rexseeCamera.takePicture();
【函数】
void takeVideo()
【函数】
void takeVideo(int quality)
【说明】
拍摄视频。拍摄成功触发事件onTakeVideoSuccessed,失败则触发onTakeVideoFailed。
【返回】
无
【参数】
quality:0表示较低质量,1表示较高质量,为方便上传,默认为0。
【示例】
rexseeCamera.takeVideo();
【函数】
void upload(String action,String name)
【说明】
将拍摄好的照片或视频直接上传。通常在onTakePictureSuccessed或onTakeVideoSuccessed事件中调用。
【返回】
无
【参数】
action:上传的服务器程序url,等同于HTML中<form action="......">中的action。
name:上传名称,等同于HTML中<input type="file" name="......">中的name。
action指向的服务器程序和HTML中表单对应的程序相同,示例的服务器程序参见rexseeUpload对象。
rexseeCamera.java源码
/*
* Copyright (C) 2011 The Rexsee Open Source Project
*
* Licensed under the Rexsee License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.rexsee.com/CN/legal/license.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package rexsee.multimedia;
import rexsee.core.browser.ActivityResult.ActivityResultListener;
import rexsee.core.browser.JavascriptInterface;
import rexsee.core.browser.RexseeBrowser;
import rexsee.core.browser.UrlListener;
import rexsee.core.lang.RexseeLanguage;
import rexsee.core.transportation.RexseeUpload;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
public class RexseeCamera implements JavascriptInterface {
private static final String INTERFACE_NAME = "Camera";
@Override
public String getInterfaceName() {
return mBrowser.application.resources.prefix + INTERFACE_NAME;
}
@Override
public JavascriptInterface getInheritInterface(RexseeBrowser childBrowser) {
return this;
}
@Override
public JavascriptInterface getNewInterface(RexseeBrowser childBrowser) {
return new RexseeCamera(childBrowser);
}
public static final String EVENT_ONTAKEPICTURESUCCESSED = "onTakePictureSuccessed";
public static final String EVENT_ONTAKEPICTUREFAILED = "onTakePictureFailed";
public static final String EVENT_ONTAKEVIDEOSUCCESSED = "onTakeVideoSuccessed";
public static final String EVENT_ONTAKEVIDEOFAILED = "onTakeVideoFailed";
public static final String URI_MEDIA_IMAGE = "content://media/external/images/media";
public static final String URI_MEDIA_VIDEO = "content://media/external/video/media";
private String mediaFile = null;
private final RexseeBrowser mBrowser;
public RexseeCamera(RexseeBrowser browser) {
mBrowser = browser;
browser.eventList.add(EVENT_ONTAKEPICTURESUCCESSED);
browser.eventList.add(EVENT_ONTAKEPICTUREFAILED);
browser.eventList.add(EVENT_ONTAKEVIDEOSUCCESSED);
browser.eventList.add(EVENT_ONTAKEVIDEOFAILED);
browser.urlListeners.add(new UrlListener(mBrowser.application.resources.prefix + ":images") {
@Override
public void run(Context context, final RexseeBrowser browser, final String url) {
new Thread() {
@Override
public void run() {
String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
html += "<BODY style='margin:0px;background-color:black;color:white;'>";
ContentResolver contentResolver = mBrowser.getContext().getContentResolver();
browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
Cursor cursor = contentResolver.query(Uri.parse(URI_MEDIA_IMAGE), new String[]{"_id", "_data"}, null, null, "_id desc");
html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
if (cursor.getCount() == 0) {
html += "<tr><td style='padding:10px;'>No image found.</td></tr>";
} else {
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToPosition(i);
html += "<tr><td onclick=\"" + browser.function.getInterfaceName() + ".go('" + URI_MEDIA_IMAGE + "/" + cursor.getInt(0) + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;'>" + cursor.getString(1) + "</td></tr>";
}
}
cursor.close();
html += "</table>";
html += "</BODY>";
html += "</HTML>";
browser.function.loadHTMLWithoutHistory(html);
}
}.start();
}
@Override
public boolean shouldAddToHistory(Context context, RexseeBrowser browser, String url) {
return true;
}
});
browser.urlListeners.add(new UrlListener(mBrowser.application.resources.prefix + ":video") {
@Override
public void run(Context context, final RexseeBrowser browser, final String url) {
new Thread() {
@Override
public void run() {
String html = "<HTML><HEAD><TITLE>" + url + "</TITLE></HEAD>";
html += "<BODY style='margin:0px;background-color:black;color:white;'>";
ContentResolver contentResolver = mBrowser.getContext().getContentResolver();
browser.progressDialog.show(RexseeLanguage.PROGRESS_ONGOING);
Cursor cursor = contentResolver.query(Uri.parse(URI_MEDIA_VIDEO), new String[]{"_id", "_data"}, null, null, "_id desc");
html += "<table width=100% cellspacing=0 style='color:white;font-size:16px;'>";
if (cursor.getCount() == 0) {
html += "<tr><td style='padding:10px;'>No video found.</td></tr>";
} else {
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToPosition(i);
html += "<tr><td onclick=\"" + browser.function.getInterfaceName() + ".go('" + URI_MEDIA_VIDEO + "/" + cursor.getInt(0) + "');\" style='border-bottom:1px solid #222222; padding:10 5 10 5;word-break:break-all;'>" + cursor.getString(1) + "</td></tr>";
}
}
cursor.close();
html += "</table>";
html += "</BODY>";
html += "</HTML>";
browser.function.loadHTMLWithoutHistory(html);
}
}.start();
}
@Override
public boolean shouldAddToHistory(Context context, RexseeBrowser browser, String url) {
return true;
}
});
}
public String getLastMediaImage() {
ContentResolver contentResolver = mBrowser.getContext().getContentResolver();
Cursor cursor = contentResolver.query(Uri.parse(URI_MEDIA_IMAGE), new String[]{"_data"}, null, null, "_id desc");
if (cursor == null || cursor.getCount() == 0) return null;
cursor.moveToFirst();
String rtn = "file://" + cursor.getString(0);
cursor.close();
return rtn;
}
public String getLastMediaVideo() {
ContentResolver contentResolver = mBrowser.getContext().getContentResolver();
Cursor cursor = contentResolver.query(Uri.parse(URI_MEDIA_VIDEO), new String[]{"_data"}, null, null, "_id desc");
if (cursor == null || cursor.getCount() == 0) return "";
cursor.moveToFirst();
String rtn = "file://" + cursor.getString(0);
cursor.close();
return rtn;
}
// JavaScript Interface
public void takePicture() {
takePicture(0);
}
public void takePicture(int quality) {
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, (quality == 0) ? 0 : 1);
mBrowser.activityResult.start(intent, new ActivityResultListener() {
@Override
public void run(int resultCode, Intent resultIntent) {
if (resultCode == Activity.RESULT_OK) {
mediaFile = getLastMediaImage();
mBrowser.eventList.run(EVENT_ONTAKEPICTURESUCCESSED, new String[]{mediaFile});
} else {
mediaFile = null;
mBrowser.eventList.run(EVENT_ONTAKEPICTUREFAILED);
}
}
});
} catch (Exception e) {
mBrowser.exception(getInterfaceName(), e);
}
}
public void takeVideo() {
takeVideo(0);
}
public void takeVideo(int quality) {
try {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, (quality == 0) ? 0 : 1);
mBrowser.activityResult.start(intent, new ActivityResultListener() {
@Override
public void run(int resultCode, Intent resultIntent) {
if (resultCode == Activity.RESULT_OK) {
mediaFile = getLastMediaVideo();
mBrowser.eventList.run(EVENT_ONTAKEVIDEOSUCCESSED, new String[]{mediaFile});
} else {
mediaFile = null;
mBrowser.eventList.run(EVENT_ONTAKEVIDEOFAILED);
}
}
});
} catch (Exception e) {
mBrowser.exception(getInterfaceName(), e);
}
}
public void prepareUpload() {
if (mediaFile == null || mediaFile == "") {
mBrowser.exception(getInterfaceName(), "Picture or video is not ready.");
} else {
RexseeUpload uploadObject = (RexseeUpload) mBrowser.interfaceList.get(mBrowser.application.resources.prefix + RexseeUpload.INTERFACE_NAME);
if (uploadObject == null) {
mBrowser.exception(getInterfaceName(), "Upload object is not ready.");
} else {
uploadObject.selectedFiles.add(mediaFile);
}
}
}
public void upload(String action, String name) {
if (mediaFile == null || mediaFile == "") {
mBrowser.exception(getInterfaceName(), "Picture or video is not ready.");
} else {
RexseeUpload uploadObject = (RexseeUpload) mBrowser.interfaceList.get(mBrowser.application.resources.prefix + RexseeUpload.INTERFACE_NAME);
if (uploadObject == null) {
mBrowser.exception(getInterfaceName(), "Upload object is not ready.");
} else {
uploadObject.clear();
uploadObject.selectedFiles.add(mediaFile);
uploadObject.upload(action, name);
}
}
}
}
仅对Rexsee的源码和函数事件做了整理,相关的demo或源码解析可以在Rexsee社区了解,目前Rexsee已提供了近2000个扩展,覆盖Android原生功能超过90%,且全部开放:
http://www.rexsee.com/
来源:oschina
链接:https://my.oschina.net/u/194999/blog/50950