Table of Contents
Android Client
For this proyect, we created an app for mobile devices, specifically for android devices. This was developed with the SL4A as we mentioned before.
This tutorial will simply explain the code of the android client. This software as the entire proyect was released within the GPLv3 License, therefore the code starts with the header for the license agreement.
#Copyright (C) 2013 Fabian Melendez B. fabmelb@gmail.com #https://wiki.arcoslab.eie.ucr.ac.cr/doku.php?id=ie0117_proyectos_2013:way_to_shop #https://github.com/gmocornejos/Way_To_Shop/wiki #This file is part of Way To Shop. #Way To Shop is free software: you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation, either version 3 of the License, or #(at your option) any later version. #Way To Shop is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. #You should have received a copy of the GNU General Public License #along with Way To Shop. If not, see <http://www.gnu.org/licenses/>.
After this, we needed a couple of imports, in order to create sockets, control the app's timing in some process and of course use the SL4A build-in's functions. Then we create the droid instance and some global variables.
import socket, android, time droid = android.Android() # ------------------------------------- Global Variables -------------------------------------- # username = "" password = "" latitude = 00 longitude = 00
Connection with the server
We decided to create a function that allows to connect with our server, for this purpose, we try to connect until it's done, because the app cant function without this connection. We try a few times (15) and if the connection it's not established we communicate it to the user.
# -----------------------------Stablishing the conection with the server------------------------------------- # #----- A function to create the socket ------ # def connectToServer(): #A boolean that indicates if the connection was successful conection = False #An int that indicates the amount of connection attempts count = 0 while (conection==False): conection = True try: #We add an attempt count += 1 #We define the client instance client = socket.socket(socket.AF_INET, socket.SOCK_STREAM #The address of the server (IP , PORT) server_address = ('192.168.1.111', 10100) #We try to connect to the server client.connect(server_address) droid.makeToast('Socket created') #We return the client instance return client #In case the connection failed except: conection = False #In case we tried to connect several times if(count == 15): droid.makeToast("Connection Error") #We restart the counter count = 1
Screens
Log in Screen
Layout
For this screen, the layout was pretty simple, we needed two text fields to receive the inputs of the username and the password (this one is special, is a password-type text-field); and also there's two buttons, one for logging in, and other for sign up.
The XML code for this layout looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/background" android:orientation="vertical" android:screenOrientation="portrait" android:configChanges="orientation" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff000000"> <EditText android:id="@+id/username" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="132dp" android:ems="10" android:inputType="textPersonName" > <requestFocus /> </EditText> <Button android:id="@+id/login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/username" android:layout_alignParentBottom="true" android:layout_marginBottom="27dp" android:text="LogIn" /> <Button android:id="@+id/signup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/login" android:layout_alignBottom="@+id/login" android:layout_alignRight="@+id/password" android:layout_marginRight="17dp" android:text="Sign Up" /> <EditText android:id="@+id/password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/pass" android:layout_centerHorizontal="true" android:layout_marginTop="26dp" android:ems="10" android:inputType="textPassword" /> <TextView android:id="@+id/pass" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/user" android:layout_centerVertical="true" android:text="Password" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/user" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/username" android:layout_centerHorizontal="true" android:layout_marginBottom="73dp" android:text="Username" android:textAppearance="?android:attr/textAppearanceLarge" />
In this layout there are somethings that important to emphasize in, for example the id of the text fields and the buttons. This we'll be used later in the event loop for the screen.
Also, its important to remember that this code will be matched to a variable, in this case its called “loginlayout” with it, and executing the print droid.fullShow(loginlayout) command, we show this layout, the result looks like this:
When the username doesn't match the password or the username isn't in our database, the login petition is denied and the user is informed about it, like this:
Event Loop
After showing the screen, the app should respond to the interaction with the user, that why an event loop function is needed, for this screen its simply called login basically it responds to two types of interaction, the login button or the sign in button .
For the LogIn button it extracts the input of the user in the username and password fields, comunicates to the server and if the username and password match with some in the database, we send the user to the menu screen, for this we close this lay out, close the current layout, and show the layout for the menu and trigger the menu function. If the username and password don't match some in the database, we comunicate it to the user.
If the user clicks on sign up, we send them to the sign up screen.
def login(client): while (True): #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the login button: if (id=="login"): username = droid.fullQueryDetail("username").result["text"] password = droid.fullQueryDetail("password").result["text"] #Comunication with the server message = "login<>"+username+"<>"+password #For checking client.sendall(message) #Waits for an answer answer = client.recv(100) #The response depends on the server's answer if (answer == "login<>success"): droid.makeToast("Logged In") droid.fullDismiss() print droid.fullShow(menulayout) #We execute the login screen decider, now on, the app controls itself with the previous methods menu(client) else: droid.maleToast("Invalid Username or Password, Try Again, or SignUp") #If it was the sign up button elif (id=="signup"): #We close the actual screen droid.fullDismiss() #We show the sign screen print droid.fullShow(signlayout) #Trigger the decider for this screen sign(client)
Sign up Screen
Layout
For the layout for the SignScreen, its needed to collect a few information from the user, like username, password, email, and his real name; for this purpose were used some textfields. And there's a couple of buttons, one for the sign petition and other one going back.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/background" android:orientation="vertical" android:screenOrientation="portrait" android:configChanges="orientation" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff00000"> <Button android:id="@+id/SignIn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/back" android:layout_alignBottom="@+id/back" android:layout_alignRight="true" android:text="SignIn" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView1" android:layout_centerHorizontal="true" android:layout_marginTop="18dp" android:text="Username:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/user" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView2" android:layout_centerHorizontal="true" android:ems="10" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/user" android:layout_centerHorizontal="true" android:layout_marginTop="27dp" android:text="Password" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/passw" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView3" android:layout_centerHorizontal="true" android:ems="10" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/passw" android:layout_centerHorizontal="true" android:layout_marginTop="17dp" android:text="Name" android:textAppearance="?android:attr/textAppearanceMedium" /> <Button android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:text="Back" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="18dp" android:text="Sign Up Information" android:textAppearance="?android:attr/textAppearanceLarge" /> <EditText android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/passw" android:layout_below="@+id/textView4" android:ems="10" /> <TextView android:id="@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/name" android:layout_centerHorizontal="true" android:layout_marginTop="17dp" android:text="Email" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/email" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/name" android:layout_below="@+id/textView5" android:ems="10" > <requestFocus /> </EditText> </RelativeLayout>
The result looks like this:
Event Loop
For the sign screen, when the user clicks the “SignIn” button, the information from in input is extracted with “droid.fullQueryDetail()” function, with this we can extract among other things, the text on a textfield. After this there's a communication with the server in order to know if the sign up petition proceeds, if so, the user is sent to the menu screen. Also if the user presses the “back” button, he's sent to the login screen again.
def sign(client): while True: #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the signup button: if id=="signin": #We extract the information from the textboxes username = droid.fullQueryDetail("user").result["text"] password = droid.fullQueryDetail("passw").result["text"] name = droid.fullQueryDetail("name").result["text"] email = droid.fullQueryDetail("email").result["text"] #We comuncate with the server message = "signup<>"+username+"<>"+password+"<>"+name+"<>"+email client.sendall(message) answer = client.recv(100) if answer == "signup<>success": droid.makeToast("Welcome! You are now sign up to Way To Shop!") #We close the current layout droid.fullDismiss() #We send the user to the menu screen droid.fullShow(menulayout) #The decider menu(client) else: droid.makeToast("Error check your username or password information") droid.fullDismiss() droid.fullShow(signlayout) sign(client) if id=="back": droid.fullDismiss() droid.fullShow(loginlayout) login(client)
Menu Screen
Layout
The layout for the menu screen its the simplest of all the layouts. It consists in two buttons, one for the scan function and one for the way to shop function. The XML code for the layout looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/background" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff00000" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" > <Button android:id="@+id/waytoshop" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/scan" android:layout_centerHorizontal="true" android:layout_marginTop="126dp" android:text="Way To Shop!" /> <Button android:id="@+id/scan" android:layout_marginTop="117dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/waytoshop" android:layout_alignParentTop="true" android:text="Scan Barcode" /> </RelativeLayout>
The result running on a phone looks like this:
Event Loop
For this loop, is only needed to respond to two buttons. Because a matter of time, the only one functioning right now is the “Scan Barcode” one. For this the first thing done is scanning the barcode, with the “droid.scanBarcode()” command. After this, the barcode is extracted from the result, and we begin to determine the GPS location (meanwhile there's a loading alert). After this there's a communication with the server, and there's two possibilities, in case the item is in our database, the user is sent to the Item-Found screen. Otherwise, he's asked if he would like to add the item, and if so, there's several information to fill, like the store he's in, for this is used a list-type of alert, for the user to pick one, or to create a new one. The code for this event loop looks like this:
def menu (client): while True: #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the signup button: if id=="scan": #We scan the barcode code = droid.scanBarcode() #Extract the code bar = code[1]['extras']['SCAN_RESULT'] #We start a loading alert droid.dialogCreateSpinnerProgress("Loading", "Please Wait") droid.dialogShow() #We start locating the client droid.startLocating() time.sleep(10) location = droid.readLocation().result #In case that the location failed, we get the last known location if (location == {}): location = droid.getLastKnownLocation().result #When we already have one known location if (location != {}): try: result = location['gps'] except: result = location['network'] #We extract the latitude and longitude from the lecture latitude = result['latitude'] longitude = result['longitude'] #address = droid.geocode(latitude, longitude).result #We stop locating droid.stopLocating() #We close the loading alert droid.dialogDismiss() #Now we comunicate with the server #seekitem<>barcode<>latitude%/longitude client.sendall("seekitem<>"+str(bar)+"<>"+str(latitude)+"%/"+str(longitude)) #We wait for an answer answer = client.recv(100) if (answer == "seekitem<>notfound"): #We ask if the user wants to add the item (By alert Box) droid.dialogCreateAlert("Item not found", "Would you like to add it?") droid.dialogSetPositiveButtonText("Yes") droid.dialogSetNegativeButtonText("No") droid.dialogShow() #Wait for a response response=droid.dialogGetResponse().result #Close the dialog droid.dialogDismiss() if response.has_key("which"): result=response["which"] #If the user answered yes we send him to the itemnotfound screen if result=="positive": #In case the user wants to add the item, we send him to the item not found screen droid.fullDismiss() droid.fullShow(itemnotfoundlayout) itemNOTfound(client, " ", " ", " ", " " , str(latitude), str(longitude) , True, str(bar)) elif result=="negative": #In this case we send the user back to the menu droid.fullDismiss() droid.fullShow(menulayout) #We execute the menu decider menu(client) #In case the item was found else: responseArray = answer.split("<>") try: #We extract the information from the message name = responseArray[1] brand = responseArray[2] quantity = responseArray[3] description = responseArray[4] image = responseArray[5] lowestprice = responseArray[6] lowestpricestore = responseArray[7] closestlowerprice = responseArray[8] closestlowerpricestore = responseArray[9] #And we show it in the item found screen droid.fullDismiss() droid.fullShow(itemfoundlayout) itemfound(name, brand, quantity, lowestprice, lowestpricestore, closestlowerprice, closestlowerpricestore, description, client, str(bar), str(latitude), str(longitude)) except: #In case it fails droid.makeToast("Error") #Back to the menu droid.fullDismiss() droid.fullShow(menulayout) #We execute the menu decider menu(client) if id == "waytoshop": #Not reay yet exit()
There are a few interesting things done with this code, for example, when the command “droid.scanBarcode()” the actual thing happening is that the Zxing Barcode Scanner app is triggered, the result looks like this:
Also, there's a loading screen, that consists of a spinner, the result looks like this:
Another resource used in this function, was the alert, in case the item wasn't found, the app asks if the user wants to add it, this is donde with an alert dialog:
Item Not Found Screen
Layout
In case the item wasn't found in our database, or if the user wants to edit an item, he's sent to the item found screen. In it there are multiple text fields, for the item's name, brand, quantity, the description, the price and the location. There are three buttons, one for going back (to the menu), another for submitting the item, and one for adding it to one list (Not functioning now). The xml code for the layout looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/background" android:orientation="vertical" android:screenOrientation="portrait" android:configChanges="orientation" android:background="#ff00000" > <Button android:id="@+id/Add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/back" android:layout_alignBottom="@+id/back" android:layout_alignParentRight="true" android:text="Add" /> <Button android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_marginBottom="23dp" android:text="Back" /> <Button android:id="@+id/submit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/Add" android:layout_alignBottom="@+id/Add" android:layout_centerHorizontal="true" android:text="Submit" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView2" android:layout_below="@+id/itemname" android:text="Brand:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/itembrand" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView3" android:layout_centerHorizontal="true" android:ems="10" /> <EditText android:id="@+id/itemname" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/itembrand" android:layout_alignRight="@+id/itembrand" android:layout_below="@+id/textView2" android:ems="10" > <requestFocus /> </EditText> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView3" android:layout_below="@+id/itembrand" android:text="Quantity:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/quantity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/itembrand" android:layout_below="@+id/textView4" android:ems="10" /> <TextView android:id="@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView4" android:layout_below="@+id/quantity" android:text="Price:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/quantity" android:layout_below="@+id/textView5" android:ems="10" /> <TextView android:id="@+id/textView6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView5" android:layout_below="@+id/price" android:text="Where?" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/store" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/price" android:layout_below="@+id/textView6" android:ems="10" /> <TextView android:id="@+id/textView7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView6" android:layout_below="@+id/store" android:text="Description:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/descript" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/store" android:layout_below="@+id/textView7" android:ems="10" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView2" android:layout_alignParentTop="true" android:text="Item Information" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/picture" style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:text="Picture" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/picture" android:text="Item:" android:textAppearance="?android:attr/textAppearanceMedium" /> </RelativeLayout>
The result looks like this:
Event Loop
For this screen, when the user submitted an item, the app shows a list of stores for the user, so he can select one o create a new one, if so, the user is presented two alerts dialogs for receiving inputs from the users. The code looks like this:
def itemNOTfound(client, name, brand, quantity, descript , latitude, longitude , new, barcode): droid.fullSetProperty("itemname", "text" , name ) droid.fullSetProperty("itembrand", "text" , brand ) droid.fullSetProperty("quantity", "text" , quantity ) droid.fullSetProperty("descript", "text" , descript ) while True: #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the back button: if id=="back": droid.fullDismiss() droid.fullShow(menulayout) #Trigger the decider for this screen menu(client) if id == "submit": #We extract the information name = droid.fullQueryDetail("itemname").result["text"] brand = droid.fullQueryDetail("itembrand").result["text"] quantity = droid.fullQueryDetail("quantity").result["text"] price = droid.fullQueryDetail("price").result["text"] location = droid.fullQueryDetail("store").result["text"] descript = droid.fullQueryDetail("descript").result["text"] #We still need to select the picture #For the store id: #We comunicate with the server to know wich stores are close client.sendall("storeinratio<>"+latitude+"%/"+longitude) answer = client.recv(100) stores = answer.split("<>") storesnames = ["New Store"] storesids = ["-1"] if len(stores)>1: for i in range (1, len(stores)-1): storesnames.append(stores[i].split("%/")[0]) storesids.append(stores[i].split("%/")[1]) #We show the user a list of stores droid.dialogCreateAlert("Please select the store you are in", "Or submit a new one") droid.dialogSetItems(storesnames) droid.dialogShow() result = droid.dialogGetResponse().result droid.dialogDismiss() if result==None: print "Error" elif result.has_key("item"): item = result["item"] #If the user selects to add a New Store if(item == 0): #We ask for the store's name droid.dialogCreateInput("New Store", "Please write the store's name") droid.dialogSetPositiveButtonText("Ok") droid.dialogShow() storename = droid.dialogGetResponse().result["value"] droid.dialogDismiss() #We ask for the store's location droid.dialogCreateInput("New Store", "Please write the store's location") droid.dialogSetPositiveButtonText("Ok") droid.dialogShow() location = droid.dialogGetResponse().result["value"] droid.dialogDismiss() client.sendall("addstore<>"+storename+"<>"+location+"<>"+latitude+"%/"+longitude) answer = client.recv(100) droid.makeToast(answer) if (answer.split("<>")[1]=="success"): #We extract the store id storeid = answer.split("<>")[2] else: droid.makeToast("Error") #We send him to the menu droid.fullDismiss() droid.fullShow(menulayout) #We execute the menu screen decider menu(client) else: storeid = storesids[item] storename = storesnames[item] #In case is a new item (Depends on the boolean "new") if (new == True): client.sendall("submititem<>"+barcode+"<>"+name+"<>"+brand+"<>"+quantity+"<>"+descript+"<>0<>"+price+"<>"+storeid) print client.recv(100) if (new == False): client.sendall("edititem<>"+barcode+"<>"+name+"<>"+brand+"<>"+quantity+"<>"+descript+"<>0<>"+price+"<>"+storeid) print client.recv(100) #We send him to the menu droid.makeToast("Thanks for adding products!") droid.fullDismiss() droid.fullShow(menulayout) menu(client) if id == "add": #In case the user wants to add it to one list #NOT FUNCTIONING NOW exit() if id == "picture": #We take the picture and store it in the default folder droid.cameraInteractiveCapturePicture("/sdcard/DCIM/Camera")
The list type of dialog was used in this screen, and it looks like this:
Item Found Screen
Layout
The layout for this screen consist almost entirely of labels that their text can be changed using a command called “droid.fullSetProperty(id, property , parameter ) ”. For this layout, the xml code looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/background" android:background="#ff000000" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:text="Item Information" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView1" android:text="Item:" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/itemname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView2" android:layout_centerHorizontal="true" android:text="ITEM NAME" android:textAppearance="?android:attr/textAppearanceMedium" android:verticalScrollbarPosition="right" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/itemname" android:text="Brand:" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/itembrand" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView4" android:layout_centerHorizontal="true" android:text="ITEM BRAND" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/itembrand" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/itembrand" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/itembrand" android:text="Quantity" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/quantity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/itembrand" android:layout_below="@+id/textView8" android:layout_centerHorizontal="true" android:text="ITEM QUANTITY" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView10" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/quantity" android:text="Lowest Price:" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/lp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView10" android:layout_marginTop="14dp" android:text="PRICE" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView12" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/lp" android:layout_centerHorizontal="true" android:text="in" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/lpstore" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textView12" android:layout_alignBottom="@+id/textView12" android:layout_alignParentRight="true" android:text="STORE" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView14" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/lp" android:layout_marginTop="22dp" android:text="Closest Lower Price" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/clp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView14" android:layout_marginTop="16dp" android:text="PRICE" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView16" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/clp" android:layout_alignBottom="@+id/clp" android:layout_alignLeft="@+id/textView12" android:layout_centerHorizontal="true" android:text="in" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/clpstore" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textView16" android:layout_alignBottom="@+id/textView16" android:layout_alignParentRight="true" android:text="STORE" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView18" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/clp" android:layout_marginTop="17dp" android:text="Description:" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView18" android:layout_marginTop="16dp" android:text="Here we show a little description" android:textAppearance="?android:attr/textAppearanceMedium" /> <Button android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_marginBottom="20dp" android:text="Back" /> <Button android:id="@+id/edit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/back" android:layout_alignBottom="@+id/back" android:layout_centerHorizontal="true" android:text="Edit" /> <Button android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/edit" android:layout_alignBottom="@+id/edit" android:layout_alignParentRight="true" android:text="Add" /> </RelativeLayout>
Event Loop
For this event loop, the first thing needed was the actualization of the parameters in the screen, then the normal interaction with the buttons.
def itemfound(name, brand, quantity, lwp, lwpst, clwp, clwpst, descrp, client, barcode, latitude, longitude): #We upate the screen droid.fullSetProperty("itemname", "text" , name ) droid.fullSetProperty("itembrand", "text" , brand ) droid.fullSetProperty("quantity", "text" , quantity ) droid.fullSetProperty("lp", "text" , lwp ) droid.fullSetProperty("lpstore", "text" , lwpst ) droid.fullSetProperty("clp", "text" , clwp ) droid.fullSetProperty("clpstore", "text" , clwpst ) droid.fullSetProperty("description", "text" , descrp ) while True: #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the back button: if id=="back": droid.fullDismiss() droid.fullShow(menulayout) #Trigger the decider for this screen menu(client) if id=="edit": #In case the user wants to edit the item #We close the current layout droid.fullDismiss() #Show the itemnotfound layout droid.fullShow(itemnotfoundlayout) itemNOTfound(client, name, brand, quantity, descrp, latitude, longitude, False, barcode) if id=="Add": print "add" exit()
Script
The full script is in here:
- androidclient.py
#Copyright (C) 2013 Fabian Melendez B. fabmelb@gmail.com #https://wiki.arcoslab.eie.ucr.ac.cr/doku.php?id=ie0117_proyectos_2013:way_to_shop #https://github.com/gmocornejos/Way_To_Shop/wiki #This file is part of Way To Shop. #Way To Shop is free software: you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation, either version 3 of the License, or #(at your option) any later version. #Way To Shop is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. #You should have received a copy of the GNU General Public License #along with Way To Shop. If not, see <http://www.gnu.org/licenses/>. import socket, android, time droid = android.Android() # ------------------------------------- Global Variables -------------------------------------- # username = "" password = "" latitude = 00 longitude = 00 # -----------------------------Stablishing the conection with the server------------------------------------- # # ---- A function to create the socket ---- # def connectToServer(): #A boolean that indicates if the connection was successful conection = False #An int that indicates the amount of connection attempts count = 0 while (conection==False): conection = True try: #We add an attempt count += 1 #We define the client instance client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #The address of the server (IP , PORT) server_address = ('192.168.1.111', 10100) #We try to connect to the server client.connect(server_address) droid.makeToast('Socket created') #We return the client instance return client #In case the connection failed except: conection = False #In case we tried to connect several times if(count == 15): droid.makeToast("Connection Error") #We restart the counter count = 1 #---------------------------------------- SCREENS METHODS --------------------------------------------------------------# #--------LOG IN SCREEN --------# # --DECIDER -- # def login(client): while (True): #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the login button: if (id=="login"): username = droid.fullQueryDetail("username").result["text"] password = droid.fullQueryDetail("password").result["text"] #Comunication with the server message = "login<>"+username+"<>"+password #For checking client.sendall(message) #Waits for an answer answer = client.recv(100) #The response depends on the server's answer if (answer == "login<>success"): droid.makeToast("Logged In") droid.fullDismiss() droid.fullShow(menulayout) #We execute the menu screen decider menu(client) else: droid.makeToast("Invalid Username or Password, Try Again, or SignUp") #If it was the sign up button elif (id=="signup"): #We close the actual screen droid.fullDismiss() #We show the sign screen droid.fullShow(signlayout) #Trigger the decider for this screen sign(client) # XML code for the graphical layout of the LOGIN SCREEN loginlayout = """ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/background" android:orientation="vertical" android:screenOrientation="portrait" android:configChanges="orientation" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff000000"> <EditText android:id="@+id/username" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="132dp" android:ems="10" android:inputType="textPersonName" > <requestFocus /> </EditText> <Button android:id="@+id/login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/username" android:layout_alignParentBottom="true" android:layout_marginBottom="27dp" android:text="LogIn" /> <Button android:id="@+id/signup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/login" android:layout_alignBottom="@+id/login" android:layout_alignRight="@+id/password" android:layout_marginRight="17dp" android:text="Sign Up" /> <EditText android:id="@+id/password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/pass" android:layout_centerHorizontal="true" android:layout_marginTop="26dp" android:ems="10" android:inputType="textPassword" /> <TextView android:id="@+id/pass" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/user" android:layout_centerVertical="true" android:text="Password" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/user" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/username" android:layout_centerHorizontal="true" android:layout_marginBottom="73dp" android:text="Username" android:textAppearance="?android:attr/textAppearanceLarge" /> </RelativeLayout>""" #--------SIGN SCREEN --------# # --Decider-- # def sign(client): while True: #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the signup button: if id=="signin": #We extract the information from the textboxes username = droid.fullQueryDetail("user").result["text"] password = droid.fullQueryDetail("passw").result["text"] name = droid.fullQueryDetail("name").result["text"] email = droid.fullQueryDetail("email").result["text"] #We comuncate with the server message = "signup<>"+username+"<>"+password+"<>"+name+"<>"+email client.sendall(message) answer = client.recv(100) if answer == "signup<>success": droid.makeToast("Welcome! You are now sign up to Way To Shop!") #We close the current layout droid.fullDismiss() #We send the user to the menu screen droid.fullShow(menulayout) #The decider menu(client) else: droid.makeToast("Error check your username or password information") droid.fullDismiss() droid.fullShow(signlayout) sign(client) if id=="back": droid.fullDismiss() droid.fullShow(loginlayout) login(client) #XML Layout signlayout = """ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/background" android:orientation="vertical" android:screenOrientation="portrait" android:configChanges="orientation" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff00000"> <Button android:id="@+id/signin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/back" android:layout_alignBottom="@+id/back" android:layout_alignRight="true" android:text="SignIn" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView1" android:layout_centerHorizontal="true" android:layout_marginTop="18dp" android:text="Username:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/user" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView2" android:layout_centerHorizontal="true" android:ems="10" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/user" android:layout_centerHorizontal="true" android:layout_marginTop="27dp" android:text="Password" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/passw" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView3" android:layout_centerHorizontal="true" android:ems="10" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/passw" android:layout_centerHorizontal="true" android:layout_marginTop="17dp" android:text="Name" android:textAppearance="?android:attr/textAppearanceMedium" /> <Button android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:text="Back" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="18dp" android:text="Sign Up Information" android:textAppearance="?android:attr/textAppearanceLarge" /> <EditText android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/passw" android:layout_below="@+id/textView4" android:ems="10" /> <TextView android:id="@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/name" android:layout_centerHorizontal="true" android:layout_marginTop="17dp" android:text="Email" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/email" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/name" android:layout_below="@+id/textView5" android:ems="10" > <requestFocus /> </EditText> </RelativeLayout> """ #--------MENU SCREEN --------# # -- Decider -- # def menu (client): while True: #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the signup button: if id=="scan": #We scan the barcode code = droid.scanBarcode() #Extract the code bar = code[1]['extras']['SCAN_RESULT'] #We start a loading alert droid.dialogCreateSpinnerProgress("Loading", "Please Wait") droid.dialogShow() #We start locating the client droid.startLocating() time.sleep(10) location = droid.readLocation().result #In case that the location failed, we get the last known location if (location == {}): location = droid.getLastKnownLocation().result #When we already have one known location if (location != {}): try: result = location['gps'] except: result = location['network'] #We extract the latitude and longitude from the lecture latitude = result['latitude'] longitude = result['longitude'] #address = droid.geocode(latitude, longitude).result #We stop locating droid.stopLocating() #We close the loading alert droid.dialogDismiss() #Now we comunicate with the server #seekitem<>barcode<>latitude%/longitude client.sendall("seekitem<>"+str(bar)+"<>"+str(latitude)+"%/"+str(longitude)) #We wait for an answer answer = client.recv(100) if (answer == "seekitem<>notfound"): #We ask if the user wants to add the item (By alert Box) droid.dialogCreateAlert("Item not found", "Would you like to add it?") droid.dialogSetPositiveButtonText("Yes") droid.dialogSetNegativeButtonText("No") droid.dialogShow() #Wait for a response response=droid.dialogGetResponse().result #Close the dialog droid.dialogDismiss() if response.has_key("which"): result=response["which"] #If the user answered yes we send him to the itemnotfound screen if result=="positive": #In case the user wants to add the item, we send him to the item not found screen droid.fullDismiss() droid.fullShow(itemnotfoundlayout) itemNOTfound(client, " ", " ", " ", " " , str(latitude), str(longitude) , True, str(bar)) elif result=="negative": #In this case we send the user back to the menu droid.fullDismiss() droid.fullShow(menulayout) #We execute the menu decider menu(client) #In case the item was found else: responseArray = answer.split("<>") try: #We extract the information from the message name = responseArray[1] brand = responseArray[2] quantity = responseArray[3] description = responseArray[4] image = responseArray[5] lowestprice = responseArray[6] lowestpricestore = responseArray[7] closestlowerprice = responseArray[8] closestlowerpricestore = responseArray[9] #And we show it in the item found screen droid.fullDismiss() droid.fullShow(itemfoundlayout) itemfound(name, brand, quantity, lowestprice, lowestpricestore, closestlowerprice, closestlowerpricestore, description, client, str(bar), str(latitude), str(longitude)) except: #In case it fails droid.makeToast("Error") #Back to the menu droid.fullDismiss() droid.fullShow(menulayout) #We execute the menu decider menu(client) if id == "waytoshop": #Not reay yet exit() #XML Layout menulayout = """ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/background" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff00000" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" > <Button android:id="@+id/waytoshop" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/scan" android:layout_centerHorizontal="true" android:layout_marginTop="126dp" android:text="Way To Shop!" /> <Button android:id="@+id/scan" android:layout_marginTop="117dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/waytoshop" android:layout_alignParentTop="true" android:text="Scan Barcode" /> </RelativeLayout>""" #--------ITEM FOUND ---------# #-- Decider --- # def itemfound(name, brand, quantity, lwp, lwpst, clwp, clwpst, descrp, client, barcode, latitude, longitude): #We upate the screen droid.fullSetProperty("itemname", "text" , name ) droid.fullSetProperty("itembrand", "text" , brand ) droid.fullSetProperty("quantity", "text" , quantity ) droid.fullSetProperty("lp", "text" , lwp ) droid.fullSetProperty("lpstore", "text" , lwpst ) droid.fullSetProperty("clp", "text" , clwp ) droid.fullSetProperty("clpstore", "text" , clwpst ) droid.fullSetProperty("description", "text" , descrp ) while True: #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the back button: if id=="back": droid.fullDismiss() droid.fullShow(menulayout) #Trigger the decider for this screen menu(client) if id=="edit": #In case the user wants to edit the item #We close the current layout droid.fullDismiss() #Show the itemnotfound layout droid.fullShow(itemnotfoundlayout) itemNOTfound(client, name, brand, quantity, descrp, latitude, longitude, False, barcode) if id=="Add": print "add" exit() #XML Layout itemfoundlayout = """ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/background" android:background="#ff000000" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:text="Item Information" android:textAppearance="?android:attr/textAppearanceLarge" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView1" android:text="Item:" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/itemname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView2" android:layout_centerHorizontal="true" android:text="ITEM NAME" android:textAppearance="?android:attr/textAppearanceMedium" android:verticalScrollbarPosition="right" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/itemname" android:text="Brand:" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/itembrand" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView4" android:layout_centerHorizontal="true" android:text="ITEM BRAND" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/itembrand" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/itembrand" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/itembrand" android:text="Quantity" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/quantity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/itembrand" android:layout_below="@+id/textView8" android:layout_centerHorizontal="true" android:text="ITEM QUANTITY" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView10" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/quantity" android:text="Lowest Price:" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/lp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView10" android:layout_marginTop="14dp" android:text="PRICE" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView12" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/lp" android:layout_centerHorizontal="true" android:text="in" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/lpstore" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textView12" android:layout_alignBottom="@+id/textView12" android:layout_alignParentRight="true" android:text="STORE" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView14" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/lp" android:layout_marginTop="22dp" android:text="Closest Lower Price" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/clp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView14" android:layout_marginTop="16dp" android:text="PRICE" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView16" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/clp" android:layout_alignBottom="@+id/clp" android:layout_alignLeft="@+id/textView12" android:layout_centerHorizontal="true" android:text="in" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/clpstore" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textView16" android:layout_alignBottom="@+id/textView16" android:layout_alignParentRight="true" android:text="STORE" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView18" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/clp" android:layout_marginTop="17dp" android:text="Description:" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView18" android:layout_marginTop="16dp" android:text="Here we show a little description" android:textAppearance="?android:attr/textAppearanceMedium" /> <Button android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_marginBottom="20dp" android:text="Back" /> <Button android:id="@+id/edit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/back" android:layout_alignBottom="@+id/back" android:layout_centerHorizontal="true" android:text="Edit" /> <Button android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/edit" android:layout_alignBottom="@+id/edit" android:layout_alignParentRight="true" android:text="Add" /> </RelativeLayout> """ #--------ITEM NOT FOUND ---------# #-- Decider --- # def itemNOTfound(client, name, brand, quantity, descript , latitude, longitude , new, barcode): droid.fullSetProperty("itemname", "text" , name ) droid.fullSetProperty("itembrand", "text" , brand ) droid.fullSetProperty("quantity", "text" , quantity ) droid.fullSetProperty("descript", "text" , descript ) while True: #Waits for an event event=droid.eventWait().result print event #If a button is clicked if event["name"]=="click": #Gets the id of the clicked button id=event["data"]["id"] #If it was the back button: if id=="back": droid.fullDismiss() droid.fullShow(menulayout) #Trigger the decider for this screen menu(client) if id == "submit": #We extract the information name = droid.fullQueryDetail("itemname").result["text"] brand = droid.fullQueryDetail("itembrand").result["text"] quantity = droid.fullQueryDetail("quantity").result["text"] price = droid.fullQueryDetail("price").result["text"] location = droid.fullQueryDetail("store").result["text"] descript = droid.fullQueryDetail("descript").result["text"] #We still need to select the picture #For the store id: #We comunicate with the server to know wich stores are close client.sendall("storeinratio<>"+latitude+"%/"+longitude) answer = client.recv(100) stores = answer.split("<>") storesnames = ["New Store"] storesids = ["-1"] if len(stores)>1: for i in range (1, len(stores)-1): storesnames.append(stores[i].split("%/")[0]) storesids.append(stores[i].split("%/")[1]) #We show the user a list of stores droid.dialogCreateAlert("Please select the store you are in", "Or submit a new one") droid.dialogSetItems(storesnames) droid.dialogShow() result = droid.dialogGetResponse().result droid.dialogDismiss() if result==None: print "Error" elif result.has_key("item"): item = result["item"] #If the user selects to add a New Store if(item == 0): #We ask for the store's name droid.dialogCreateInput("New Store", "Please write the store's name") droid.dialogSetPositiveButtonText("Ok") droid.dialogShow() storename = droid.dialogGetResponse().result["value"] droid.dialogDismiss() #We ask for the store's location droid.dialogCreateInput("New Store", "Please write the store's location") droid.dialogSetPositiveButtonText("Ok") droid.dialogShow() location = droid.dialogGetResponse().result["value"] droid.dialogDismiss() client.sendall("addstore<>"+storename+"<>"+location+"<>"+latitude+"%/"+longitude) answer = client.recv(100) droid.makeToast(answer) if (answer.split("<>")[1]=="success"): #We extract the store id storeid = answer.split("<>")[2] else: droid.makeToast("Error") #We send him to the menu droid.fullDismiss() droid.fullShow(menulayout) #We execute the menu screen decider menu(client) else: storeid = storesids[item] storename = storesnames[item] #In case is a new item (Depends on the boolean "new") if (new == True): client.sendall("submititem<>"+barcode+"<>"+name+"<>"+brand+"<>"+quantity+"<>"+descript+"<>0<>"+price+"<>"+storeid) print client.recv(100) if (new == False): client.sendall("edititem<>"+barcode+"<>"+name+"<>"+brand+"<>"+quantity+"<>"+descript+"<>0<>"+price+"<>"+storeid) print client.recv(100) #We send him to the menu droid.makeToast("Thanks for adding products!") droid.fullDismiss() droid.fullShow(menulayout) menu(client) if id == "add": #In case the user wants to add it to one list #NOT FUNCTIONING NOW exit() if id == "picture": #We take the picture and store it in the default folder droid.cameraInteractiveCapturePicture("/sdcard/DCIM/Camera") #XML Layout itemnotfoundlayout = """ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/background" android:orientation="vertical" android:screenOrientation="portrait" android:configChanges="orientation" android:background="#ff00000" > <Button android:id="@+id/Add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/back" android:layout_alignBottom="@+id/back" android:layout_alignParentRight="true" android:text="Add" /> <Button android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_marginBottom="23dp" android:text="Back" /> <Button android:id="@+id/submit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/Add" android:layout_alignBottom="@+id/Add" android:layout_centerHorizontal="true" android:text="Submit" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView2" android:layout_below="@+id/itemname" android:text="Brand:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/itembrand" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView3" android:layout_centerHorizontal="true" android:ems="10" /> <EditText android:id="@+id/itemname" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/itembrand" android:layout_alignRight="@+id/itembrand" android:layout_below="@+id/textView2" android:ems="10" > <requestFocus /> </EditText> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView3" android:layout_below="@+id/itembrand" android:text="Quantity:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/quantity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/itembrand" android:layout_below="@+id/textView4" android:ems="10" /> <TextView android:id="@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView4" android:layout_below="@+id/quantity" android:text="Price:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/price" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/quantity" android:layout_below="@+id/textView5" android:ems="10" /> <TextView android:id="@+id/textView6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView5" android:layout_below="@+id/price" android:text="Where?" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/store" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/price" android:layout_below="@+id/textView6" android:ems="10" /> <TextView android:id="@+id/textView7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView6" android:layout_below="@+id/store" android:text="Description:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/descript" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/store" android:layout_below="@+id/textView7" android:ems="10" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView2" android:layout_alignParentTop="true" android:text="Item Information" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/picture" style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:text="Picture" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/picture" android:text="Item:" android:textAppearance="?android:attr/textAppearanceMedium" /> </RelativeLayout> """ #----------------------------------------------------------------------------------------------# #------------------------------------A Kind of Main--------------------------------------------# #----------------------------------------------------------------------------------------------# #First We Connect To the Server client = connectToServer() #We show the loginlayout droid.fullShow(loginlayout) #We execute the login screen decider, now on, the app controls itself with the previous methods login(client)