Secret Android Camera in Python (computer controlled)

This is project has been on my mental TODO list for some time now. I finally sat down and finished it. We’re creating a remote controlled camera where the remote is our computer and the camera is in our Android cell phone.

See a Demo

This video shows the end result. Take a look.

YouTube: Secret Android Camera in Python

What You’ll Need

When I did this project I had a budget of $0.00, i.e., I didn’t spend any money on it. Here are the things I already had.

  • Android Smart Phone (I used Droid X)
  • Computer with Python installed. You should have 2.6 but I used 2.7 and it worked fine.
  • SL4A and Python installed on your Droid.
  • A router that you can change administration settings on
  • An FTP account (optional)

The Setup

The first problem I ran into was my router. We’re going to be using sockets so one of our devices needs to be a server. Due to security concerns, the is usually disabled. A web search like, “ port forwarding” should help you with this. I ended up using the reset button on my router to change the pas0sword. You want to pick a number somewhere between 5000 and 8000 and set that to forward. Write this number down for later.

Now make sure you have Python installed. If your on Windows you might need to install it from here. Linux users should already have it.

Install SL4A on your phone. If you have a bar code / qr code app, you can scan to download here.

The Scripts

Since we are using two devices, we need two scripts. You’ll need to make some changes based on what you did in the previous steps.

Client

This is our client script which runs on our Droid.

# Echo client program
import socket, android, time
droid = android.Android()

HOST = '123.456.123.456'    # The remote host
PORT = 12345              # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Connecting...'
s.connect((HOST, PORT))

def getTempFile():
    out = '/sdcard/caps/cap-'
    out += time.strftime("%Y-%m-%d--%H-%M-%S", time.localtime())
    out += '.jpg'
    return out

def upload(fp):
    from ftplib import FTP
    ftp = FTP('ftp.REMOVED.tld')
    ftp.login('REMOVED', 'REMOVED')
    ftp.storbinary('STOR caps/' + tempFile[12:], open(fp, 'rb'))
    ftp.quit()

data = True
while data:
    print 'Sending...'
    s.send('REQUEST')
    data = s.recv(1024)
    if data and data == 'PIC':
        tempFile = getTempFile()
        droid.cameraCapturePicture(tempFile,True)
        print 'Uploading...'
        upload(tempFile)
        s.send('http://publicdomain.tld/' + tempFile[12:])
#    if data and data == 'DOWN':
#        s.send('UP')
s.close()

You’ll need to set the IP of your computer/server, and the port you opened earlier. Also, if you’re going to upload it to a FTP account, set your account details. If you remember, we said FTP was optional. If you don’t have an account remove the upload(tempFile) line. This script doesn’t delete the pictures from your phone either way, so you can copy them to your computer later.

Server

We’ll be running this on our home computer. All you need to change here is the port it uses. If you don’t have firefox and/or firefox isn’t in your PATH, you’ll have to change the os.system(…) line too.


# Echo server program
import socket

HOST = ''                 # Symbolic name meaning the local host
PORT = 12345              # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    if data == 'REQUEST':
        print "Press ENTER to capture"
        cmd = raw_input().strip().upper()

        # allow the user to exit and close the socket
        if cmd == 'EXIT' or cmd == 'DIE': break
        conn.send('PIC')
        print 'Sending picture request...'
        url = conn.recv(4096)
        if '&' not in url and '|' not in url and url.startswith('http://'):
            import os
            os.system('firefox ' + url)
        print url
conn.close()

Get Spying

Run the server on your computer, and then the client on your phone. With any luck you should see “Press ENTER to capture”. Now you can put your phone in the window so you always know who’s ringing the door bell.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>