Thursday, May 9, 2013

Controlling your Android phone through USB


There is an Android debugging tool called ADB that among other things lets you emulate keystrokes on your phone. For this to work your phone needs to be connected to your pc via USB, with your phone set to USB debugging mode:

Settings -> Developer options -> USB debugging -> On

You will also need to install drivers for your phone, in the case you (like me) have an HTC phone, you will need to install HTC Sync to get the driver.

ADB tools is part of the Android ADT bundle for windows or you can download it as a .zip file from my Google Drive here.

ADB is a command line program, so you'll run it through cmd.
An example:
adb shell input keyevent 66 - Will emulate pressing the enter-key

Now if you combine this with the ability to start intents (like the sms-dialog) you can make some useful scripts that you can automate in a regular .bat file.

adb shell am start -a android.intent.action.SENDTO -d sms: PHONENUMBER --es sms_body MESSAGE --ez exit_on_sent true  - This will open the sms-dialog, just swap insert a phonenumber and message.

And if you follow that by keyevent 22 (pad right to select the "send" button) and keyevent 66 (pressing enter to actually send the message) you now have the ability to send sms messages from you computer.
I do admit this is a rather flaky experience, since selecting the right button using predetermined keystrokes might fail on runtime if you for example have an app open on you phone when the script is executed. Or if your phone enters sleep and the screen locks before running the script.
But atleast it looks abit cool/scary seeing you phone type stuff without you touching it.

This is the full list of keyevents :
0 --> "KEYCODE_UNKNOWN"
1 --> "KEYCODE_MENU"
2 --> "KEYCODE_SOFT_RIGHT"
3 --> "KEYCODE_HOME"
4 --> "KEYCODE_BACK"
5 --> "KEYCODE_CALL"
6 --> "KEYCODE_ENDCALL"
7 --> "KEYCODE_0"
8 --> "KEYCODE_1"
9 --> "KEYCODE_2"
10 --> "KEYCODE_3"
11 --> "KEYCODE_4"
12 --> "KEYCODE_5"
13 --> "KEYCODE_6"
14 --> "KEYCODE_7"
15 --> "KEYCODE_8"
16 --> "KEYCODE_9"
17 --> "KEYCODE_STAR"
18 --> "KEYCODE_POUND"
19 --> "KEYCODE_DPAD_UP"
20 --> "KEYCODE_DPAD_DOWN"
21 --> "KEYCODE_DPAD_LEFT"
22 --> "KEYCODE_DPAD_RIGHT"
23 --> "KEYCODE_DPAD_CENTER"
24 --> "KEYCODE_VOLUME_UP"
25 --> "KEYCODE_VOLUME_DOWN"
26 --> "KEYCODE_POWER"
27 --> "KEYCODE_CAMERA"
28 --> "KEYCODE_CLEAR"
29 --> "KEYCODE_A"
30 --> "KEYCODE_B"
31 --> "KEYCODE_C"
32 --> "KEYCODE_D"
33 --> "KEYCODE_E"
34 --> "KEYCODE_F"
35 --> "KEYCODE_G"
36 --> "KEYCODE_H"
37 --> "KEYCODE_I"
38 --> "KEYCODE_J"
39 --> "KEYCODE_K"
40 --> "KEYCODE_L"
41 --> "KEYCODE_M"
42 --> "KEYCODE_N"
43 --> "KEYCODE_O"
44 --> "KEYCODE_P"
45 --> "KEYCODE_Q"
46 --> "KEYCODE_R"
47 --> "KEYCODE_S"
48 --> "KEYCODE_T"
49 --> "KEYCODE_U"
50 --> "KEYCODE_V"
51 --> "KEYCODE_W"
52 --> "KEYCODE_X"
53 --> "KEYCODE_Y"
54 --> "KEYCODE_Z"
55 --> "KEYCODE_COMMA"
56 --> "KEYCODE_PERIOD"
57 --> "KEYCODE_ALT_LEFT"
58 --> "KEYCODE_ALT_RIGHT"
59 --> "KEYCODE_SHIFT_LEFT"
60 --> "KEYCODE_SHIFT_RIGHT"
61 --> "KEYCODE_TAB"
62 --> "KEYCODE_SPACE"
63 --> "KEYCODE_SYM"
64 --> "KEYCODE_EXPLORER"
65 --> "KEYCODE_ENVELOPE"
66 --> "KEYCODE_ENTER"
67 --> "KEYCODE_DEL"
68 --> "KEYCODE_GRAVE"
69 --> "KEYCODE_MINUS"
70 --> "KEYCODE_EQUALS"
71 --> "KEYCODE_LEFT_BRACKET"
72 --> "KEYCODE_RIGHT_BRACKET"
73 --> "KEYCODE_BACKSLASH"
74 --> "KEYCODE_SEMICOLON"
75 --> "KEYCODE_APOSTROPHE"
76 --> "KEYCODE_SLASH"
77 --> "KEYCODE_AT"
78 --> "KEYCODE_NUM"
79 --> "KEYCODE_HEADSETHOOK"
80 --> "KEYCODE_FOCUS"
81 --> "KEYCODE_PLUS"
82 --> "KEYCODE_MENU"
83 --> "KEYCODE_NOTIFICATION"
84 --> "KEYCODE_SEARCH"
85 --> "TAG_LAST_KEYCODE"

Saturday, March 9, 2013

Linux is so intuitive!

Messing about with my linux desktop, i find myself googling the same stuff over and over again. Like, "how to install .deb files" my linux box is also my mediacenter making SSH my only keyboard-friendly interface.

Im here just dumping some commands, as a dictionary for myself mostly, and for others who might tend to google these things too:


install .deb package: (dpkg much more intuitive word than "install")
    sudo dpkg -i package.deb

remove file:
    rm "filename"

remove directory:
    rmdir "dirname"

remove directory with files in it (whyyyy so retarded?)
    rm -rf "dirname"

navigate to folder:
    cd "folder"

navigate back:
    cd ..

unzip tarballs: (i'm so glad it's not the same command for every extention)
        (zxf is so easy to remember. unzip would make no sense at all)
    tar zxf file.tar.gz
     tar zxf file.tgz
     tar jxf file.tar.bz2
     tar jxf file.tbz2

edit user permissions (and also lock yourself out of your system):
    sudo visudo

add something to startup:
    sudo nano /etc/rc.local
    (then add your command to the file before "exit 0")

Well, atleast there is no long hexadecimal error codes like in windows:



Thursday, February 7, 2013

Access .mdb database file from C#

My newest project requires me to keep a database with the email addresses of my clients, which my program will read and write to. To avoid the hassle of setting up a SQL server, and also since i'm familiar with using Microsoft Access, i decided on going with a database-in-file solution.


This presented the problem of figuring out how to do all this in C#, and after a good bit of googling i hacked together a class that retrieved the contacts list from the .mdb file as a DataTable, that i could show in my DataGridView by setting it as the DataSource:

private void Form1_Load(object sender, EventArgs e)
        {
            // Populate the dataGridView with the database content
            dataGridView1.DataSource = mdb_reader_class.readContactsTable();
            // Set proper column sizes
            dataGridView1.Columns[0].Width = 30;
            dataGridView1.Columns[1].Width = 200;
            dataGridView1.Columns[2].Width = 230;

            // Dont allow the user to resize the form (it's perfect as is)
            this.FormBorderStyle = FormBorderStyle.FixedSingle;

            // This goes for maximize button as well
            this.MaximizeBox = false;
        }
The mdb_reader_class.readContactsTable method:


public static DataTable readContactsTable()
{
    try
    {
        // Variables that will be used 
        string AccessDB = "folder-path\\Contacts.mdb";
        DataTable MyDataTable = new DataTable();

        // using an ridiculously long connection string, 
        // only reluctant to change it since it works
        OleDbConnection lConn;
        lConn = new OleDbConnection(
        "Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=" +
        AccessDB + ";Mode=Share Deny None;Extended Properties='';
        Jet OLEDB:System database='';
        Jet OLEDB:Registry Path='';Jet OLEDB:Engine Type=4;
        Jet OLEDB:Database Locking Mode=0;
        Jet OLEDB:Global Partial Bulk Ops=2;
        Jet OLEDB:Global Bulk Transactions=1;
        Jet OLEDB:Create System Database=False;
        Jet OLEDB:Encrypt Database=False;
        Jet OLEDB:Don't Copy Locale on Compact=False;
        Jet OLEDB:Compact Without Replica Repair=False;
        Jet OLEDB:SFP=False"
        );

        // connect to database
        lConn.Open();

        // using SQL 
        // Where 'Contacts' is the name of the table in the MDB file
        string lSQL = "Select ID, Name, Email from Contacts";  
        
        //This assigns the Select statement and connection of the data adapter
        OleDbDataAdapter dadapt = new OleDbDataAdapter(lSQL, lConn);  
        //This builds the update and Delete-
        //queries for the table in the above SQL. 
        //this only works if the select is a single table.
        OleDbCommandBuilder cb = new OleDbCommandBuilder(dadapt);    

        // populate the dataTable
        dadapt.Fill(MyDataTable);

        //Then save to the MDB file 
        dadapt.Update(MyDataTable);
        lConn.Close();

        // then return the datatable
        //dataGridView1.DataSource = MyDataTable;
        return MyDataTable;
    }
    catch (Exception)
    {
        // if an exception is thrown, a empty table is returned,
        // with one column named "Error"
        DataTable errorTable = new DataTable();
        errorTable.Columns.Add("Error!", typeof(string));
        return errorTable;
    }
}

Thursday, January 31, 2013

Send mail from your gmail account with C#

I'm currently working on a new project. I'm supposed to read from a USB temperature sensor, and log the temperature. And if the temperature is below a certain threshold temperature the application will warn the client thru mail.


And so now i have at least gotten the SendMail class working, and ready for implementation with the rest of the program. So here is the source code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Mail;

namespace TempNET
{
    class SendMail
    {
        public string sendMail(string recieverMailAddress, string recieverName, string messageSubject, string messageBody)
        { // method for sending mail
            try
            {
                // using a GMail account
                var fromAddress = new MailAddress("gmailaccount@gmail.com", "Senders name"); 
                var toAddress = new MailAddress(recieverMailAddress, recieverName);
                const string fromPassword = "gmailaccount password";

                // create smtp client object containing all needed info
                var smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com",
                    Port = 587,
                    EnableSsl = true,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = false,
                    Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
                };
                // create mail
                using (var message = new MailMessage(fromAddress, toAddress)
                {
                    Subject = messageSubject,
                    Body = messageBody
                })
                {
                    smtp.Send(message);
                }
                // mail sendt successfully
                return "Mail sendt";
            }
            catch (Exception ex)
            {
                // something failed, return error message
                return "Error: " + ex.Message;
            }
        }
    }
}

Monday, January 21, 2013

My first Python app for Android, and it works!

I tried making a simple app for controlling the RaspberryPi lights controller i made earlier. It was to be a simple script, only really making a POST to a web-interface hosted on my LAN. However, simple tasks get really complex when the only tool you have is the most alien-ass backwards developing studio kit-SDK i have ever laid my eyes on. Yes im talking about AndroidADT/Eclipse.

God, please explain to me why a simple project template that only displays a blank screen need to consist of 131 Files divided across 66 Folders?!


And why does my 4 core computer, sporting 8Gb of ram and another gig of VRAM load for an amount of time that surely involves the Avogadro constant before it's able to run my simple app (displaying a blank screen). Yea, it... aint great.

So after Android-ADT and Eclipse just pissed me off to no end i decided Java could go fuck itself; my time is better spent on Python.

To run and develop Python on Android you need a Python interpreter installed on your phone. This was the main thing putting me off Python for phones in the first place, as it adds some complexity for the end user. But in my case that's usually just me anyways. Pluss it's really just an app that you need to download:
QPython+ and it's on google play store (for free).

QPython+ has a nice, no bullshit userinterface, and comes with some preinstalled libs, a text-editor and a debugger. Everything you need to develop, debug and run Python on your phone.

This below is my app in Python; 1 file, 0 folders. If my math is correct the complexity dropped by exactly half an infinity:

import urllib
# you need urllib to connect to the url
import androidhelper
# androidhelper is included in QPython+
# gives easy access to lots of android stuff, like GUI

droid = androidhelper.Android() 

def turnLights():
 # This displays a dialog with 3 options
 # Program loops untill user wants to exit
 while True:  
     title = 'Light switch:'
     droid.dialogCreateAlert(title)
     droid.dialogSetItems(['On', 'Off', 'Exit'])
     droid.dialogShow() 
     response = droid.dialogGetResponse().result['item']
     if response == 0:
            # The app connects to one of two url's
            # The web server at that url determines what
            # to do based on the page requested
            urlon = "http://192.168.1.6:8080/?turn=on"
            sock = urllib.urlopen(urlon)
            content = sock.read() 
            sock.close()
            print content
     elif response == 1:
            urloff = "http://192.168.1.6:8080/?turn=off"
            sock = urllib.urlopen(urloff)
            content = sock.read() 
            sock.close()
            print content
     elif response == 2: 
            # The user pressed Exit
            break 
# Run the app    
turnLights()

Python for Android is just awesome. Each app starts out as just one simple .py file. Easy as that. My app takes up 699 bytes. And i did bug-fixes and debugging on my phone and used the on-screen keyboard to add a couple of missing indents.

 My simple, beautiful app; a functioning light switch:


Sunday, January 20, 2013

Add a python script to startup

Im rather new to linux, and this was the first time ever that i had to get a python script running at boot, and with root privileges.
Have to say it was rather straight forward. Nothing special for python, just had to add a line of code in
/etc/local.rc
Just opened it in nano:
sudo nano /etc/local.rc

 
and added to the file:
sudo python /home/pi/turn.py


Wednesday, January 16, 2013

C# code to switch lights thru web-interface

Using the WebBrowser controll in Visual Studio 2010 it's really easy to make a interface to access the web and send data.

The code below is what makes up the desktop app that uses my python web interface to switch lights.

private void button1_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate("http://192.168.1.6:8080/?turn=on");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate("http://192.168.1.6:8080/?turn=off");
        }

The app is just a web browser that navigates to my web-interface with the click of the buttons. Displaying the web interface in the small browser window.