Outreachy- Week 6 & 7 Progress

Working with Date, Calendar, SimpleDateFormat   in Android.

As I mentioned In my last blog, I would talk about how I used Calendar and Date classes for the user to designate silent mode by setting time constraints and weekdays, in Lumicall.

Date class to used to interpret dates as year, month, day, hour, minute, and second values.

I had to compare whether the current time falls between Start Time and End Time specified by the user. So that, silent mode can be enabled within that time frame.

I used Calendar Class to get the current hour in 24-Hour format and minute.

 Calendar now = Calendar.getInstance();

 int hour = now.get(Calendar.HOUR_OF_DAY);  

 int minute = now.get(Calendar.MINUTE);

Now, Since the user enters the Time in EditText Widgets, the values were retrieved as strings.
String hhStart, mmStart, hhEnd, mmEnd store these values from Edit text widgets.

To interpret these strings as a representation of a date and time, we need to parse it

A “Date” class object’s format looks like-

unnamed
Since, I was only interested in fetching the HH:MM values, i.e the fourth field in the format,

To set and compare only the HH:MM values, Android provides lovely, SimpleDateFormat class to access the particular value we want in the Date object.
To access the year, use letter Y
To access the time zone, use letter z
To access the Hour and minute, we use letter H and m.

SimpleDateFormat simpleDateFormat= new SimpleDateFormat(“HH:mm”, Locale.ENGLISH);

Date currentTime = parseDate(hour + ":" + minute)

Date timeCompareOne = parseDate(hhStart +”:”+mmStart);  

Date timeCompareTwo = parseDate(hhEnd +”:”+mmEnd);


Rest everything in the date object are values set by default. Eg, Year 1970. Which we din’t set / access , hence did not change.

To check if the start time is before the current time. And the endtime is after the current time, 

if(timeCompareOne.before(currentTime) && timeCompareTwo.after(currentTime))

{

Switch on the silent mode;

}

Added a try catch block to handle the exception which will arise if the SimpleDateFormat.parse method is unable to parse the given Java String.

public Date parseDate(String date)  
{ 
try 
{  
return inputParser.parse(date);
} 
catch (java.text.ParseException e)  
{  
return new Date(0);  
}  
}

Comparing Time? Done!
Now to check whether the selected weekday in the checkboxes matches the current week day,

Calendar calendar = Calendar.getInstance(); 

int day = calendar.get(Calendar.DAY_OF_WEEK); 

If it’s sunday, value returned by calendar.get(Calendar.DAY_OF_WEEK) is 1, if monday, 2 and so on..
Weekdays compared too! 🙂

Thanks for reading,
U

Outreachy- Week 4 & 5 Progress

Working with Preferences, AudioManager, RingtoneManager   in Android.

Sometimes the noise can get too much. Imagine all the people around you at work or in a classroom. All of them have at least one cell phones. Even if they were all to make a tiny blip, the noise would be irritating and disruptive.

To avoid devices from interrupting the non-digital life, applications often provide settings that allow users to modify app volumes. My task this week was to  enable/disable silent mode in Lumicall.

To provide settings for your application, instead of using multiple Views, Preference APIs should be used.

Each preference appears as an item in a list and provides the appropriate UI for users to modify the setting.

In Lumicall, when settings menu from the menubar is selected, a preference screen is displayed showing various setting options, where I appended a “Configure Silent Mode” option.

The UI for the preference screen is expected to be in Src->xml folder under the name preferences.xml

silent

Snippet from Lumicall’s preference.xml for Configure Silent Mode preference screen.

 

In Lumicall, whenever a SIP message comes in, RingtoneManager  Class is used to generate a notification sound & AudioManager Class is used to generate sound for incoming encrypted calls.

The difference between the two is that, AudioManager provides access to volume and ringer mode control. Ringer modes like, Normal, silent and vibration.  Whereas RingtoneManager provides access to ringtones, notification.

So to add a simple -disable/enable silent mode- functionality, I decided to use a CheckboxPreference. For the same goal, a better looking widget would be a SwitchPreference, but It does not work properly with DarkThemes which Lumicall uses. So I decided to use a simple Checkbox instead.

The result of all the settings are  saved as key value pairs in the default  SharedPreferences file which can be retrieved to make changes in the app based on the settings modified by the user.
Every preference has a key and the result associated with it.
To fetch the result from the SharedPreferences file-
boolean silentflag=PreferenceManager.getDefaultSharedPreferences(ctx).getBoolean(org.sipdroid.sipua.ui.Settings.PREF_SILENT_MODE, org.sipdroid.sipua.ui.Settings.DEFAULT_SILENT_MODE);

Note, the arguments in getBoolean function is  (Key, DefaultValue).

Don’t forget to pass the Context object, ctx in the statement. I wasted a lot of time figuring that one out and created a non-optimal-working way which I eventually had to remove cos I figured out how to retrieve the result value.

frustrated
To add a second method of setting silent mode, i.e where the user can enter his work days/time, I wanted to display an activity with required widgets .
To display an activity on a when a preference is selected, intent tags are used. (See the above snippet)
Note that the target package in the intent tags is not the package name of where the java file of the activity is to be found.It’s the package name which is your applicationID.

Now this activity, like any other activity in android is a combination of an xml and java file.
1. My xml file contains the widgets for user to enter two set of time value in HH:MM format. i.e.the start and end time during which user requires application notifications to be silent it also contains checkboxes for user to select multiple days of the week.

2. The java file associated with this does the following:
2.1 Comparing the Real Time with User’s Specified Start and End time
2.2 Checking the current day of the week with the days marked by the user in the      checkboxes

I have used inbuilt Calendar class and Date class to accomplish this.

All done I felt quite proud but this.. this was something that tested my patience and endurance!
As I continue my work, I will keep sharing!

 

Please keep reading!
U

Outreachy- Week 3 Progress

In my previous blog I had tried to explain what White Labelling is and my approach of implementing it in Lumicall.

This week I went ahead with the implementation by using productFlavors feature in Android. I baked my cake!


I’ve created two flavors :

  1. Lumicall (which runs like the default version)
  2. Whitelabel

To switch to the desired version, there is a build variant window on the bottom left of Android Studio, when you open it, you can change your current active flavor from the ones you defined.

So the idea is, there would be different flavors for each client. And all the client specific resources would go under src/(flavorname) folder.

The client specific resources could be:

  1. Application name
  2. Client’s logo (Drawable)
  3. Details about the client’s organization which would go under “about” tab
  4. Colors / Themes (Colors.xml)
  5. Strings (Strings.xml)
  6. Additional Files which include new features

To understand how to modify these resources in the flavored version, Let’s take an example in which we would like to replace the application name from  from Lumicall to, lets say “ClientApp”.

  1. Go to file : /res/values/strings.xml which has the application name <string name=”app_name”>Lumicall</string>
  2. To replace it with client’s app name, You’d have to create a new strings.xml file (Note : Same name as that of the existing ‘strings.xml file’)  in the directory LumicallWhitelabel/src/whitelabel/res/values/strings.xml

    So, in our project, there are two strings.xml file. One is /res/values/strings.xml and one flavored specfic file in LumicallWhitelabel/src/whitelabel/res/values/strings.xml.

    Only add the values which would be different in the flavor version.
    If there are particular things which you’d like to be same, then there is no need of adding them again with the same value in the flavored file.


    -Just define the values you would want to replace. Not the values you would like to be same-

    Gradle will take care of the overwriting while merging the resources when you run the flavored version.

Now, the most important thing is changing the Application ID. In my previous blog I explained the difference between ApplicationID and package name.

I also added  a snippet from my build.gradle file which would suffix “.whitelabel” at the end of the orignal applicationID. So for configuring ApplicationID for each flavor, add applicationIdSuffix’suffix_you_want’.

Link to the the cake : https://github.com/Urvika-gola/LumicallWhitelabel

Thanks for reading,
U

Outreachy- Week 1,2 Progress

Working with productFlavors  in Android.

Since the past few weeks I have been researching and working on  creating a white label version of Lumicall with my mentors Daniel, Juliana and Bruno.

Lumicall is a free and convenient app for making encrypted phone calls from Android. It uses the SIP protocol to interoperate with other apps and corporate telephone systems. Think of any app that you use to call others using an SIP ID.

What does it mean to make a  “white label” version of Lumicall?
White labelling is the idea of taking the whole or piece of Lumicall’s code by business users and tweaking it according to their requirements and functionality they want.

The white label version would have client’s name, logo, icons, themes etc which reflect their brand. Although, the underlying working of both the applications would be same.

Think of it like getting a cake from the local bakery, putting it into a home baking dish and passing it off as something you made in front of your friends and earning all the praise. Except cake is more appealing than apps.
What whitelabelling does is it takes away the pain of collecting cake ingredients, mixing them in right proportion, baking at the right temperature and uses the experience of one cake base to create more and more fancier, prettier, grander cakes. This lets the cool bakers (or the business users of lumicall) to focus on other aspects of the party like decoration, games and drinks (or monetization, publicity and new features)


Now you would wonder who these cool bakers or business users of lumicall would be?

  • Existing SIP providers can use white label version of Lumicall to expand their business and launch SIP client. This would provide a one stop shop for them!!
  • New SIP clients/developers can use Lumicall white label version to get the underlying working of making encrypted phone calls using SIP protocol, it will help them to focus on other additional functionalities they would like to include.
  • Moreover,  Companies that have existing clients such as shopping apps, social network apps can benefit from integrating lumicall to launch new business ideas

While researching this work that despite the commonalities, there would need to be a unique identifier for any application in the app store.

I found that there is difference between the package name and the applicationID. When I create a new project in Android Studio, the applicationId exactly matches the Java-style package name I chose during setup. However, the application ID and package name are independent of each other beyond this point. The thing to keep in mind is that app stores identify as a changed application ID as a different app altogether.

So if I were to make  N separate copies of the application code for N clients, it would be a maintenance nightmare, If the build system is Gradle, using product flavors is a trick that will make this maintenance easier. Instead of N separate copies, I would simply have N product flavors. Each flavor corresponds to a customized version of my application. Pro, free, whitelabel, Debug  (for development purposes), Release (for production purposes) are the basic flavors I have identified.  

Each flavor would use the same source code and files of the application but resources, icons, manifests etc that are specific to each flavor can be defined again in main/src/flavor_name directory under res folders etc. according to the requirement.

Here is a snippet from my build.gradle file::

snippetcrop

Note: You have to define at least two flavors to be able to build multiple variants.
Because once you have flavors, you can only build “flavored” application. You can’t just build “default” configuration anymore. Define an empty flavor, with no applicationIdSuffix at all, and it will use all of the default config section.

This week I’d be moving forward with the implementation of whitelabelling using productFlavors in Lumicall.
I would love to hear from someone who has done this before!
Comment here or email me and I promise you an excellent home-made-store-brought cake!

Wishing you all HAPPY HOLIDAYS! ! 🙂
-U

Reaching out to Outreachy

The past few weeks have been a whirlwind of work with my application process for Outreachy taking my full attention.

When I got to know about Outreachy, I was intrigued as well as dubious.  I had many unanswered questions in my mind. Honestly, I had that fear of failure which prevented me from submitting my partially filled application form. I kept contemplating if the application was ‘good enough’, if my answers were ‘perfect’ and had the right balance of du-uh and oh-ah!
In moments of doubt, it is important to surround yourself with people who believe in you more than you believe in yourself. I’ve been fortunate enough to have two amazing people, my sister Anjali, who is an engineer at Intel and my friend, Pranav Jain  who completed his GSoC 16 with Debian. 
They believed in me when I sat staring at my application and encouraged me to click that final button.

When I initially applied for Outreachy, I was given a task for building Lumicall and subsequent task was to examine a BASH script which solves the DNS-01 Challenge.
I deployed the DNS-01 challenge in Java and tested my solution against a server.
Within a limited time frame, I figured things out and wrote my solution in Java and then eagerly  waited for the results to come out. Going through a full cycle of :

lifecycle.JPG

I was elated with joy when I got to know I’ve been selected for Outreachy to work with Debian. I was excited about open source & found the idea of working on the project open source fun because of the numerous possibilities of contributing towards a  voice video and chat communication software.

My project mentor, Daniel Pocock, played a pivotal role in the time after I had submitted my application. Like a true mentor, he replied to my queries promptly and guided me towards finding the solutions to problems on my own. He exemplified how to feel comfortable with developing on open source. I felt inspired and encouraged to move along in my work.

Beyond him, The MiniDebConf  was when I was finally introduced to the Debian community. It was an overwhelming experience and I felt proud to have come so far..  It was pretty cool to see JitsiMeet being used for this video call. I was also introduced to two of my mentors , Juliana Louback & Bruno Magalhães . I am very excited to learn from them.

I am glad I applied for Outreachy which helped me identify my strengths and I am totally excited to be working with Debian on the project and learn as much as I can throughout the period.

I am not a blog person, this is my first blog ever! I would love to share my experience with you all in the hopes of inspiring someone else who is afraid of clicking that final button!