Thursday, August 22, 2013

Basic4Android - Baby Flashcard

This is a very simple application in Basic4Android, a paid tool (~$100), where you can program an Android device in Visual Basic (almost fully compatible). If I understand it correct, it is a wrapper that takes the VB and turns it into java, before running it through the Android SDK and generating the apk.

The app displays images every 5 seconds that pulls from a folder. It also pulls an mp3 with the same name which plays some audio (for instance, the name of the object being displayed). That way, a baby can see an object, say an apple, hear apple, see "apple" written below, and then move randomly to the next object.

The app illustrates a bit of a GUI/display images, access to files, mediaplayer, timer and multithreading.
 'Bits: flash cards present for my one year old nephew  
 '8/18/2013  
 'The program opens randomly a picture from a language directory, and the same name .mp3 file from that directory.  
 'Options eventually will include to select the directory (therefore, several languages can be selected), select the time  
 'the pic is in display, and to mute the voice, so, that the parents can be the ones saying the word. Also we want to have   
 'the option to pass card with the press of a Button.  
 'To avoid accidental exits, as the baby may touch the screen with the hand, the exit of presentation mode (to go into the   
 'menu) works by pressing two buttons at the same time.  
 'Thanks to Gigatron (GTR) as I looked at some of his code for learning...  
 'Now we want the system to cover the screen, no matter what screen and orientation...  
 'Changing things with reference to 100% is not enough as everything is bound by Panel.  
 'See for that the two lines of code below.  
 'Then we refer the position of the objects also respect to the screen/Activity (% notation)  
 'Notice that the notation is top and left. So, 0% means all the way to the left, and all the   
 'way to the top.  
 'Things explained in detail in page 72 of the beginners guide.  
 '  
 'Then, we finally add to it the capability to rotate the screen. For that, all what we need to do is to go   
 'to "Project>>Orientations supported" AND change it To "both" (it was in "landscape").  
 'In other words, if both are allowed, when we rotate the screen, the activity is recreated   
 'with the new reference axis following the position of the tablet. Otherwise, the axis just  
 'follow the orientation.  
 '  
 'We will present an image every number of seconds, with timer, eventually selected by customer, but we will load the  
 'files in the background process.   
 '   
 'With every timer click the UI will make sure the loading process is done, then take the info and move it to a   
 'save place before running again the loading thread. Not sure the copy works for MediaPlayer elements, so, I have two  
 'player objects and I switch from one to the other. Play one while loading the other.  
 'Activity module  
 Sub Process_Globals  
      'These global variables will be declared once when the application starts.  
      'These variables can be accessed from all modules.  
      Dim time As Timer  
 End Sub  
 Sub Globals  
      'These global variables will be redeclared each time the activity is created.  
      'These variables can only be accessed from this module.  
      Dim cnv As Canvas  
      Dim graphpanel As Panel  
      Dim clr As Int       
      Dim Label1 As Label  
      Dim Orientation As String  
      'Directory name to be selected by menu  
      Dim Question_Number,Old_Question_Number As Int  
      Dim FileList As List       
      Dim Card_Name, Card_Name_Buffer As String  
      Dim Card, Card_Buffer As Bitmap  
      Dim SrcRect, DestRect As Rect  
      Dim MP1,MP2 As MediaPlayer 'One is loaded while the other is played  
      Dim MP1_Busy As Boolean  
      'Dim tic As Int 'Number of seconds in each picture  
      Dim LoadFiles As Thread  
 End Sub  
 Sub Activity_Create(FirstTime As Boolean)  
           Activity.LoadLayout("bitsscreen")  'nothing special just graphpanel + 1 imageView in layout  
           graphpanel.Width=100%x  
           graphpanel.Height=100%y  
           Label1.Width=100%x  
           Label1.Height=20%y  
           Label1.TextSize=15%y  
           Label1.Left=50%x-Label1.Width/2  
           Label1.Top=80%y  
           Label1.Gravity=Gravity.CENTER_HORIZONTAL  
           FileList=File.ListFiles("/sdcard/Pictures/bits")  
           cnv.Initialize(graphpanel)  
           MP1.Initialize2("MP")  
           MP2.Initialize2("MP")  
           MP1_Busy=False  
           Load_card  
           LoadFiles.Initialise("GO")  
           time.Initialize("time",1000)  
           time.Enabled=True  
 End Sub  
 Sub Activity_Resume  
   time.Enabled = True  
           time_Tick  
 End Sub  
 Sub Activity_Pause (UserClosed As Boolean)  
   If MP1.IsPlaying Then MP1.Pause  
           If MP2.IsPlaying Then MP2.Pause  
   time.Enabled = False  
 End Sub  
 Sub time_Tick  
      time.Enabled=False   
      Do While LoadFiles.Running==True   
      Loop  
      MP1_Busy=Not(MP1_Busy)  
      Card=Card_Buffer  
      Card_Name=Card_Name_Buffer  
      Old_Question_Number=Question_Number  
      LoadFiles.Start(Me,"Load_card", Null)  
      time.Initialize("time",5000)  
      time.Enabled=True  
      Show_card  
 End Sub  
 Sub Show_card          'This shows whatever image was on the buffer when timer call it  
      Dim ratio As Float   
      Dim Rec As Rect  
      Rec.Initialize(0,0,100%x,100%y)  
      cnv.DrawRect(Rec,Colors.White,True,5dip)  
      Label1.Text=Card_Name       
      SrcRect.initialize(0,0,Card.Width,Card.Height)  
      'Fit picture to the limits without distorting  
      ratio=100%x/Card.Width  
      If (ratio>80%y/Card.Height)     Then  
           ratio=80%y/(2*Card.Height)  
           DestRect.initialize(50%x-Card.Width*ratio,0,50%x+Card.Width*ratio,80%y)  
      Else  
           ratio=ratio/2  
           DestRect.initialize(0,40%y-Card.Height*ratio,100%x,40%y+Card.Height*ratio)  
      End If  
      cnv.DrawBitmap(Card,SrcRect,DestRect)  
  graphpanel.Invalidate ' invalidate panel after drawing the stars (make it visible)            
      If MP1_Busy=True Then   
           MP1.Play  
      Else   
           MP2.Play  
      End If  
 End Sub  
 Sub Load_card     'This loads an image in the background  
      Dim ratio As Float   
      Question_Number=Rnd(0,FileList.Size)  
      Card_Name_Buffer=FileList.Get(Question_Number)  
      Do While (File.IsDirectory("/sdcard/Pictures/bits",Card_Name_Buffer) OR _  
           Not(Card_Name_Buffer.EndsWith(".jpg")) OR (Question_Number==Old_Question_Number))  
           Question_Number=Rnd(0,FileList.Size)  
           Card_Name_Buffer=FileList.Get(Question_Number)  
      Loop       
      Card_Buffer.Initialize("/sdcard/Pictures/bits",Card_Name_Buffer)  
      Card_Name_Buffer=Card_Name_Buffer.SubString2(0,Card_Name_Buffer.Length-4)  
      If MP1_Busy==True Then   
           MP2.Load("/sdcard/Pictures/bits",Card_Name_Buffer&".mp3")   
      Else  
           MP1.Load("/sdcard/Pictures/bits",Card_Name_Buffer&".mp3")         
      End If  
 End Sub  

PS.: And no, I am not going backwards from Java into Basic4Android. :) I started a year ago on Basic4Android because it was easier for me to ramp up but then I decided to learn Java... Now I still go to Basic4Android as I am more familiar with its libraries, but only till I get better with the Android SDK :)

No comments:

Post a Comment