Spycam
Start a WEBrick web server
Access the camera
require
'monitor'
require
'camera_helper'
require
'ruboto/util/stack'
class
SpycamServer
extend
MonitorMixin
PORT
=
4567
DOC_ROOT
=
"#{$activity.files_dir.absolute_path}/"
@@server
=
nil
def
self.start(activity,
server_status_view)
Thread.with_large_stack(512)
do
synchronize
do
if
@@server.nil?
activity.run_on_ui_thread
{
server_status_view.text
=
"Loading"
}
require
'webrick'
activity.run_on_ui_thread
{
server_status_view.text
=
"Loaded"
}
@@server
=
WEBrick::HTTPServer.new(:Port
=>
PORT,
:DocumentRoot
=>
DOC_ROOT)
@@server.mount_proc('/')
do
|req,
resp|
case
req.path
when
'/',
'index.html'
CameraHelper.take_picture(activity)
resp.content_type
=
"text/html"
resp.body
=
'
Spycam
'
raise
WEBrick::HTTPStatus::OK
when
'/latest.jpg'
resp.content_type
=
"image/jpg"
resp.body
=
$camera_data
$camera_data
=
nil
raise
WEBrick::HTTPStatus::OK
else
resp.body
=
"Unknown
path:
#{req.path.inspect}"
raise
WEBrick::HTTPStatus::NotFound
end
end
server
=
@@server
Thread.new{server.start}
require
'ruboto/activity'
require
'ruboto/widget'
require
'spycam_server'
import
android.util.Log
import
android.view.Surface
import
android.view.WindowManager
ruboto_import_widgets
:Button,
:LinearLayout,
:ScrollView,
:TextView
ruboto_import_widget
:SurfaceView,
"android.view"
class
SpycamActivity
def
on_create(bundle)
rotation
=
{
Surface::ROTATION_0
=>
0,Surface::ROTATION_90
=>
90,Surface::ROTATION_180
=>
180,Surface::ROTATION_270
=>
270
}[window_manager.default_display.rotation]
self.title
=
"Spycam
#{rotation}"
#
self.setRequestedOrientation(android.content.pm.ActivityInfo::SCREEN_OR
IENTATION_PORTRAIT)
window.add_flags(WindowManager::LayoutParams::FLAG_KEEP_SCREEN_ON)
setContentView(linear_layout(:orientation
=>
:vertical)
do
linear_layout
do
text_view
:text
=>
"Server:
"
@server_status_view
=
text_view
end
linear_layout
do
text_view
:text
=>
"Picture:
"
@camera_status_view
=
text_view
end
sv
=
surface_view
sv.holder.add_callback
RubotoSurfaceHolderCallback.new(rotation)
#
Deprecated,
but
still
required
for
older
API
version
sv.holder.set_type
android.view.SurfaceHolder::SURFACE_TYPE_PUSH_BUFFERS
end)
end
def
set_camera_status(value)
@camera_status_view.text
=
value
end
def
camera_status=(value)
run_on_ui_thread
{
$activity.set_camera_status
value
}
end
def
on_resume
class
CameraHelper
def
self.take_picture(activity)
activity.camera_status
=
"Set
volume..."
am
=
activity.getSystemService(android.content.Context::AUDIO_SERVICE)
old_volume
=
am.get_stream_volume(android.media.AudioManager::STREAM_SYSTEM)
am.set_stream_volume(android.media.AudioManager::STREAM_SYSTEM,
0,
0)
activity.camera_status
=
"Taking
picture..."
picture_taken
=
false
$camera.take_picture(nil,
nil)
do
|data,
camera|
$camera_data
=
String.from_java_bytes(data)
activity.camera_status
=
"Gotcha!"
$camera.start_preview
am.set_stream_volume(android.media.AudioManager::STREAM_SYSTEM,
old_volume,
0)
picture_taken
=
true
end
sleep
0.1
until
picture_taken
end
end