Tuesday, September 4, 2012

Android Room Manager


During my year as a Graduate Assistant at Carnegie Mellon University, Silicon Valley, I worked on an Android tablet application, Android Room Manager, which allowed students and staff to quickly reserve meeting rooms at the university. This post contains some screenshots from the application, which can be seen running on Android 3.0 (Honeycomb). I will make future posts outlining how the app was developed completely from scratch.




56 comments:

  1. Helo,
    Similar thinks i"m looking for.. I"m also doing some room manager application, but i don get any idea about how to start.. If you don mind plz help to find some solution and ur help also... It"s very gud GUI that i seen...

    Thanks in advance
    Anoop
    anoop@syosys.com

    ReplyDelete
  2. First, you should take a look at how managing calendars works via the Google APIs. For this, you must learn how to log into Google with the account registed on the Android device via OAuth2 (see http://stackoverflow.com/questions/8435228/google-calendar-api-oauth2-troubles-on-android-honeycomb ). Next, for the UI itself, please see http://stackoverflow.com/questions/9355747/how-can-i-create-a-weekly-calendar-view-for-an-android-honeycomb-application . The UI can be done many ways. I used existing elements that are part of the Android Honecomb package. The basic idea is to have a ScrollView with eight columns (one for the timestamps and one for each day of the week). Please let me know if this helped or if you have any more questions.

    ReplyDelete
  3. Hello BVB, first of all I want to apologize for my questions but I’m a total beginner in Android programming.
    I’m trying to program an application that should have a calendar function (3 different views: day, week and month) ; I pretended to use the Google calendar, but I have been investigating and I suppose this is not possible. That’s how I arrive to your blog (first via your post on stackoverflow.com ).
    I will do what you recommend (on studding the Google Calendar API), but I have a lot of doubts regarding also to your .xml file and your final solution and UI:
    How do you manage to put the correct day number at the top of the calendar? I suppose you added another TextView for each number and you change the text via program from de .java file, is it?
    In your .xml file I see that you create buttons in order to represent the appointments in the schedule, I suppose that this was just a trial ant that on your final app you should create them dynamically, Am I right?, can you please guide me on how to do this or recommend me an example to follow?
    Finally, I would appreciate if you can tell me how to make appear a monthly calendar next to your weekly one. Have you used fragment or is there another way? Can you help me with the layout of the monthly version of the calendar?

    Thank you very much!

    Miguel

    mgrdiez@hotmail.com





    ReplyDelete
  4. Hello Miguel,
    Thanks for the reply! I’m going to try to tackle your questions one by one.

    Q: How do you manage to put the correct day number at the top of the calendar? I suppose you added another TextView for each number and you change the text via program from de .java file, is it?
    A: That is correct, I added a TextView for each number and then change the text via a .java file. I have a class with a private variable that stores the displayed Sunday’s date.

    Q: In your .xml file I see that you create buttons in order to represent the appointments in the schedule, I suppose that this was just a trial ant that on your final app you should create them dynamically, Am I right?, can you please guide me on how to do this or recommend me an example to follow?
    A: That is also correct – in the final app, I have made a custom “event” view that I place into the calendar. Each of the day columns is conveniently 24 x 60 dp high (24 hours of 60 dp each, thus 1 dp is equal to 1 minute, making things easier). Thus, if I want to add a 1-hour long event at 01:30 AM, I just add the event view 90 dp from the top of the column with a height of 60 dp.

    Q: Finally, I would appreciate if you can tell me how to make appear a monthly calendar next to your weekly one. Have you used fragment or is there another way? Can you help me with the layout of the monthly version of the calendar?
    A: For the monthly calendar on the side I used the Calendar view. See http://developer.android.com/reference/android/widget/CalendarView.html

    As a bonus, here’s an updated XML for the calendar layout: http://pastie.org/private/onznryv6igdeoilhogdmw

    Best,
    BVB

    ReplyDelete
  5. Thank you very much for your feedbak! by the way, congratulations for your blog, it is very interesting! I will go into your answers to see if I can get up with the app.

    I suppose I'll come back with more questions soon...

    Regards from Barcelona!


    Miguel

    ReplyDelete
  6. Hey BVB, there is a mistake with the link that you posted: http://pastie.org/private/onznryv6igdeoilhogdmw

    I get an error screen...

    Thanks!

    ReplyDelete
  7. Hmm, that's weird. Try this one: http://pastebin.com/jT4wQxeb

    ReplyDelete
  8. Thanks BVB, I just downloaded your new XML but wasn't able to prove it because I have a lot of references lost.

    Based in your first XML, and getting some elements of the Calendar View I got a very nice-looking layout right now (not so professional but as a first try is ok!).

    I'll try no to get it functional (with the Google Calendar API)...

    Thanks!

    ReplyDelete
  9. Hello BVB, finally I adapt some of your last XML to my project (Thank you very much for your help so far!), but I have some doubts regarding to the time marker line and how to make it functional.

    I'm trying to "move" it from the .java class with these lines:

    int dipValue = 720; // we want to convert this dip value to pix
    Resources r = getResources();
    float pix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
    dipValue, r.getDisplayMetrics());

    LinearLayout lay = (LinearLayout) findViewById(R.id.currentTimeMarkerLinearLayout);
    LinearLayout.LayoutParams lp = lay.getLayoutParams();
    lp.setMargins(0, (int) pix, 0, 0);
    lay.setLayoutParams(lp);



    But I get an error:

    Type mismatch: cannot convert from ViewGroup.LayoutParams to LinearLayout.LayoutParams

    Any idea what I'm doing wrong?

    Thanks!

    ReplyDelete
  10. I got the solution!!! Post the same question on stackoverflow and they helped me (answer in: http://stackoverflow.com/questions/13744056/type-mismatch-cannot-convert-from-viewgroup-layoutparams-to-linearlayout-layout).

    ReplyDelete
  11. Nice! For issues that are Android-specific rather than calendar-specific, it may be best to search StackOverflow first, as you may find your answer very quickly.

    ReplyDelete
    Replies
    1. That's right BVB, they answer very quick! I have one specific question for you, because my view is very nice but it is also very slow to inflate (I remember that you asked the same on StackOverflow)Did you get to optimize this inflate time?
      if yes, How do you get it?

      Thank you!

      Delete
    2. What do you mean (could you link me to that StackOverflow post)? Are you using the emulator or an actual Android device? I have been using the device only, as I found the emulator much too slow for my liking.

      Delete
    3. I'm so sorry, I thought that you said something about your layout being slow, but I just reviewed it (http://stackoverflow.com/questions/9355747/how-can-i-create-a-weekly-calendar-view-for-an-android-honeycomb-application) and you only ask if there is a better way to accomplish that...

      I'm using also an Android device, everything is ok but the agenda is a little bit slow... My app is suppose to be a kind of CRM, so I need to give clients access to a calendar. If I select the calendar from my dropdown menu, it takes approximately 10-12 seconds to inflate the view (it doesn't have any connectivity to Google Calendar yet).

      Do you need a similar amount of time to inflate yours?

      Thanks in advance!

      Miguel

      Delete
    4. Hmm, not really. My layout inflates fairly quickly - almost instantaneous. Have you tried setting a few breakpoints and seeing where it could be hanging up? Is it the layout inflation itself? Also, which device are you using? I tested my code on the first Samsung Galaxy Tab running Honeycomb and on the Motorola XOOM running Ice Cream Sandwich.

      Delete
    5. Hello BVB and sorry for the delay in my answer but I have been stuck trying to get connection to Google Calendar.

      Answering to your questions I'm using a brand new Samsung Tablet running ICS for testing my app, so I guess my problem is not that.

      Last week I tried to just inflate the layout and it was very slow also, so I googled looking for advice and I don't remember where I read that you could evaluate the performance of your device from Eclipse using a method profiling from the device window. I do that and almost instantly the performance was better (it inflates the view almost instantaneously). Unfortunately after my unsuccessful tries and retries to connect to the calendar, I got back to the previous situation...

      Any way, Can you give me some tips on connecting to Google Calendar. I have followed almost all examples available on the Internet but I don't get it.

      I just don't understand the exact process of getting the authorization... I tried to follow the tutorial that you recommend on (http://stackoverflow.com/questions/8435228/google-calendar-api-oauth2-troubles-on-android-honeycomb) but I get lost... And if you search for an example of code on the same page, they perform the connection an authorization in a very different way...

      Is there any code where I can follow to succeed on this? This is driving me crazy...

      Thank you very much!


      Miguel

      Delete
    6. That one is the hard part - it really depends on the modern APIs. The ones I used were very old, so the code may not be applicable anymore. Also, it took me a very long time to get it to work (2+ months on authentication alone). Check out OAuth2 tutorials - search for something like "OAuth2 Google Calendar API".

      Delete
    7. Ok thanks for the tip, I'll continue searching for the answer. One last question, you use Oauth2 on your project, right?

      Delete
  12. i like your idea , it's brilliant , this is exactly what i'm looking for , so when can you post the full sample ?

    thx

    ReplyDelete
    Replies
    1. Hello Anass,

      Check out my replies to Miguel, as well as some of my stackoverflow posts on the subject. They should give you a good starting platform that you can pull ideas from to create a custom application that is perfect for your needs.

      Delete
  13. Hi BVB, I am trying to do a week calender like the one mentioned here. I got here from stack overflow. I gone through your layouts but i cannot understand how the code behind would work. My events come from a database.

    ReplyDelete
    Replies
    1. Hi! Check out this code for the layout itself: http://pastebin.com/jT4wQxeb

      Notice how I have a bunch of relative layouts titled mondayRelativeLayout, tuesdayRelativeLayout, etc.? These are containers for event elements. You can create a custom event element and dynamically size and place them into the appropriate columns at the appropriate location. This should be done via Java code rather than XML. There are plenty of sources available on how to do this. A quick search of StackOverflow returned http://stackoverflow.com/questions/6661261/how-to-add-dynamic-content-to-lineary-layout-programmatically-in-my-case

      Here's an order of steps you could follow:
      1. Create a layout for your weekly calendar
      2. Learn how to dynamically add elements to the columns of your calendar
      3. Determine the ratio between event lengths and element height (I used 1 minute = 1 dp)
      4. From your list of events, you should have a start time and end time for a given event. Use this to calculate the height of the element, as well as the y position.

      Hope this helps!

      Delete
  14. Thanks for the response. I can do all that. I have done something similar with the day view similar to Google calender on ICS. I am having trouble with the code behind handling the calender. e.g Getting the dates on the Day Headers dynamically (which will change when user browses through the calender) and handling multiple columns. How did you set up the adapter for all this? I have been struggling with this for a while and can't figure out a graceful solution.

    ReplyDelete
  15. What I did for the dates was store the date of the first day of the week. Then, when week is changed by the user (or automatically), I update the stored date to the first date of the week one of whose days was just selected.

    Using http://4.bp.blogspot.com/-03APCA3XXL4/UEbboRP-hQI/AAAAAAAAAJ0/SOR4UR5nANw/s1600/3_ARM_MainActivity_CMUSV.png as an example, say the user selects August 8th. The date of the Sunday would then be updated to August 5th (see sundayDateTextView in my xml). Using this date we can then calculate the next six dates for Tuesday through Saturday.

    You will want to make a function and call it whenever the first day of the week is to be changed on the calendar. Updating the content of a TextView should be simple via the setText function.

    ReplyDelete
  16. thank you for sharing this!
    did you implement the swipe? how?

    thanks
    Matteo

    ReplyDelete
    Replies
    1. I actually did not implement the swiping gesture for the calendar. The only gesture it supported was a long press (tap and hold) for adding a calendar event at a specific time. For swipe, check out this link: http://stackoverflow.com/questions/4139288/android-how-to-handle-right-to-left-swipe-gestures

      See Mirek's reply for an example. Hope it helps!

      Delete
    2. thanks!
      i've implemented swipe even if it's not cool... the frame don't move while swiping... :)
      bye
      matteo

      Delete
  17. Hey BVB can you post the source for Android room manager?

    ReplyDelete
    Replies
    1. I am unable to post the full source as it contains proprietary information. There should be plenty of information here to help you develop something similar.

      Delete
  18. I can't get idea about calendar_zebra.xml, why it is used?

    ReplyDelete
    Replies
    1. calendar_zebra is used as the background for each day. It contains 23 horizontal lines spaced 60dp apart. The space between a pair of adjacent lines represents an hour (think 1 dp = 1 minute). There are different ways of going about this.

      Delete
  19. Can you please send me it on vrstest123@gmail.com

    ReplyDelete
  20. BVB thanks for your valuable reply, its help me to move towards my thinking. Now what i want to do is, i want to add a event for perticular time, then how can i achive this by clicking on a time slot.

    ReplyDelete
    Replies
    1. You should be able to use onLongClick(). Within the event handler, simply check which "coordinate" the user pressed at. You can then use that coordinate to figure out the time at which the event should be created. In my implementation, I rounded to the nearest half hour. For example, if the user long clicked at 12:35 PM, I would round that to 12:30 PM.

      Delete
  21. hi BVB, this is a beautiful app. Is this project still close-sourced? I am looking to implement similar weekly calendar view so I would like to re-use, scrub, and customize if possible.

    If not, do you mind sharing with me the layout in calendar_zebra.xml? I can be reached at hsunami4@gmail.com

    Thanks a lot!

    ReplyDelete
    Replies
    1. Hello Tom,

      The project is still closed source, but you will find a lot of the source code in the comments of this post. The most difficult thing is getting the XML layouts down. Everything else is rather simple - just modify the layouts as necessary, for example, when an event is created.

      Good luck,

      BVB

      Delete
    2. Thanks BVB. I will look at the comments more closely.

      Delete
    3. Hi BVB, As a novice, I couldn't figure out how I should layout the calendar zebra xml. Can you give me some direction?
      Is it a vertical linear layout with:
      59dp of empty view and 1 dp of horizontal divider?

      Delete
    4. Yup, that should do it! You will have 24 dividers total, with one being at the very bottom. Total height should be 24 x 60 dp, not accounting for the top border.

      Delete
  22. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. You can simply use android:layout_marginTop/Left to set x and y coordinates within a RelativeLayout.

      Delete
  23. can you share calendar_zebra.xml to manjunatha.amg@gmail.com

    ReplyDelete
    Replies
    1. The zebra is simply a 60 * 24 = 1440dp high layout with a 1 dp high horizontal view with a solid background placed every 60dp. Each represents a marker for an hour of time.

      Delete
  24. How do you get the vertical border between the days? I am guessing it is the reference to @drawable/bordered_rectangle?

    ReplyDelete
    Replies
    1. You have a couple of options: you can either add a view with a solid rectangle drawable background between each of the columns, or you can create a bordered rectangle drawable and set it as the background of each column.

      Delete
  25. I assume that your App is able to navigate to the next and previous week as does the one I am working on. I am having trouble removing the the view's of scheduled appointments when navigating through the weeks (The blocks that say Busy with date and time in the screenshots you posted). Do you have any advice or can you provide some insight on the way that you are doing this? I have sucessfully removed them by setting view.setVisibility(View.GONE) but I have some very strange behavior. As in it only removes them one time even though the code runs across the setVisibilty method everytime a week is navigated.

    ReplyDelete
    Replies
    1. When a week is selected in the CalendarView on the right side, all of the views from the day column are removed (the visibility isn't changed to View.GONE). You can use the viewGroup.removeAllViews() call to achieve this. Another thing you can do is use a "loading" view to cover the calendar area and remove it only after all events have been loaded in for the appropriate week.

      Delete
  26. Hi there,

    I am in my planning phase for creating a calendar app. I was thinking of using a horizontal listview so that someone could infinitely scroll between days within the week view. I was wondering if you looked into this at all, and whether it was the right way to go in comparison to the design you chose in the end.

    Thanks

    ReplyDelete
    Replies
    1. Yes, I think that us a great idea! My design flaw is there is no smooth way to transition between weeks. A horizontal scroll view (well, an all-directional one because it's bad practice to put a scroll view in a scroll view) or a view pager would be far superior designs to use over just a static week.

      Delete
  27. Hi there,

    Thanks for your weekly timetable layout, its very interesting, this give me a great start for my android app project. I got here from stack overflow since i still new to android. There is 1 part for calendar_zebra.xml i still cant really get the picture of how it should coded after i checked the comments "calendar_zebra is used as the background for each day. It contains 23 horizontal lines spaced 60dp apart. The space between a pair of adjacent lines represents an hour (think 1 dp = 1 minute). There are different ways of going about this." and this "Yup, that should do it! You will have 24 dividers total, with one being at the very bottom. Total height should be 24 x 60 dp, not accounting for the top border." i still cannot get it, do you mind if you can do a simple sketch for that? and my English is quite bad too, sorry about that

    ReplyDelete
  28. Sir can I get the source code for the application in eclipse...m a newbee in developing android apps..
    thank you..

    ReplyDelete
  29. mail me the zip file if possible..
    yogigotu1234@gmail.com

    ReplyDelete
  30. Hey BVB,
    Just wanted to thank you for such a great post thats helping so many people build their own version. I am doing the same and your post has been very resourceful in guiding me towards building my own version. I got the layout going and in my implementation, I am using the calendar layout within a Popup Window where the user makes a selection from availabilities (Ex: anytime between 9am and 2pm). Currently I am not able to handle and touch events, I set an onTouchListener on calendarSplitter, calendarRelativeLayout, almost every layout to try to handle touch events but none are able to successfully register a touch event. For some reason the touch event seems to be getting consumed somewhere higher up the view hierarchy. I did some research on handling touch events only to have more questions than answers, so I thought I would ask you about any tips or suggestions on how I should go about it, I know you mentioned setting up an onLongClick() and using coordinates. I am sure I should be able to figure things out, but at this point it does not even reach the touch event callback for the layouts. If you could give me some pointers on how you think I should go about it, that would lead to a massive karma upgrade :)
    Thanks and cheers!
    Angad
    angad.aux@gmail.com

    ReplyDelete
    Replies
    1. Hello HoppyWanderer,

      Do you have an onTouchListener set somewhere in a view that is on top of the calendarSplitter? If any onTouchListener for such a view returns true, the event is consumed prior to getting to the correct layout. Without seeing your layout and code, I would not be able to help beyond this.

      OnLongClickListener allows you to process a long-press event on a view. To get the coordinates that were pressed on, you will have to save them in an OnTouchListener. Here's some info on how to get them relative to the parent view: http://stackoverflow.com/questions/9612357/get-touch-event-coordinates-relative-to-the-parent

      I hope this helps :)

      Delete
  31. Hello
    can you please mail me your bordered_rectangle.xml and calendar_zebra.xml code.
    khanabir42@gmail.com

    ReplyDelete