Quick Tip: git Auto-complete

When I started using git, it peeved me that there is no auto-complete. More so when you have to manually do a git add manually.

Thank heavens I found this little gem. Making auto-complete work for git:

In terminal:
<pre class="brush:shell">curl https://raw.github.com/git/git/master/contrib/completion/git-completion.bash -o ~/.git-completion.bash</pre>

And then you’d need to “activate” it in your .bash_profile:
<pre class="brush:shell">if [ -f ~/.git-completion.bash ]; then
. ~/.git-completion.bash
fi</pre>

~1 min read

Quick Tip: Updating the location update frequency

When using Google Play’s Location Services and you want to change the frequency of the updates, make sure to do these in order:

<pre class="brush:java">stopLocationUpdates();
// This method should implement mLocationClient.removeLocationUpdates()

// Set the new frequency in your location client
updateLocationClient(frequency);

startLocationUpdates();
// This method should implement mLocationClient.requestLocationUpdates()
// which means it should check for isConnected() as well!</pre>
If you do not remove the updates before updating the frequency, it looks like the old frequency update is still active BUT a new one is started.

~1 min read

Setting up the SeekBar

So we want to use the SeekBar. We want the minimum value to be 10 and the maximum value to be 100, and it should increment by 10.

Thing is, SeekBar by default always starts at 0, and the increment is always an int. It is definitely possible to get what we want, but we need to do some simple math first.

Compute how many increments you will need from your minimum up to your maximum:
<pre class="brush:xml">numberOfIncrements = maximum - minimum = 90</pre>
Then divide it by the amount of each increment we want:
<pre class="brush:xml">seekBarMaximum = numberOfIncrements / 10 = 9</pre>
This means we should set up the SeekBar to have max = 9 and increment = 1. Then in our code, we have to figure out how to get the actual progress that we want.
<pre class="brush:java">SeekBar.OnSeekBarChangeListener mSeekbarListener = new OnSeekBarChangeListener() {

@Override
public void onStopTrackingTouch(SeekBar seekBar) { /* Do nothing/ }

@Override
public void onStartTrackingTouch(SeekBar seekBar) { /
Do nothing*/ }

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mProgressDisplay.setText(“Seekbar is at: “ + getProgressToDisplay(progress));
}
};


private String getProgressToDisplay(int progress) {</pre><pre class="brush:java"> // We are multiplying by 10 since it is our actual increment
int actualProgress = (progress + 1) * 10;
return String.valueOf(actualProgress);
}</pre>
Another example:
<pre class="brush:xml">minimum = 1, maximum = 10, increment = 0.5
numberOfIncrements = 9
seekBarMaximum = 18</pre>
In this case, the contents of getProgressToDisplay() will change since the increment is not a whole number.
<pre class="brush:java">private String getProgressToDisplay(int progress) {
float actualProgress = (progress + 1) - (progress * 0.5f);
return String.valueOf(actualProgress);
}</pre>

1 min read

Styling tab selectors for ActionBarSherlock

This post builds on the previous post for ABS + VPI.

I have gotten a lot of questions on styling the ABS, specifically the tab selected indicators. This task may seem daunting, but in reality it is relatively simple. I am also quite confused why I didn’t find any straightforward tutorials when I tried googling this. Anyway, this post will hopefully help developers who aim to style their action bars.

We will need to use Jeff Gilfelt’s awesome styling tool. To use it, just input in your app’s color scheme for the highlights and what-not then download the generated zip file. If you want to just change the tab underline color, change the value under “Accent color”. To make the change obvious from the default settings, I have used a shade of orange for the tab selected indicators. Here are the settings I used for this demo.

Jeff’s tool conveniently generates all the XML files and drawables and organizes them into the correct /res/drawable folders. Unzip the file and just drag the generated files into your project, or merge the contents if you already have such existing files.

See how easy it was? Seriously, we should all lie prostrate at Jeff Gilfelt’s and Jake Wharton’s feet. These guys are AWESOME.

The two photos below show the difference between the old app and the styled app. As you can see, I only changed the tab selected color. You can explore what happens if you use the other styles you can get from Jeff’s tool.
<table align="center" cellpadding="10" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody><tr><td style="text-align: center;"></td><td style="text-align: center;"></td></tr><tr><td class="tr-caption" style="text-align: center;">Default</td><td class="tr-caption" style="text-align: center;">Styled</td></tr></tbody></table>The hard work is done, let’s now try to understand the automagically generated configurations we did.

First, we have to configure the theme to use custom tab indicators. We do this by changing the tab styles in themes.xml. In my sample app, these lines customize the tabs we are using.
<pre class="brush:xml"><!– Styling the tabs –>
<style name=”CustomTabPageIndicator” parent=”Widget.TabPageIndicator”>
 <!– Tab text –>
<item name=”android:textSize”>15dip</item>
<item name=”android:textColor”>#FFB33E3E</item>

<!– Lines under tabs –>
<item name=”background”>@drawable/tab_indicator_ab_styling_abs</item>
<item name=”android:background”>@drawable/tab_indicator_ab_styling_abs</item>
</style></pre>
The “drawable” tab_indicator_ab_styling_abs is actually a state list drawable that provides different images for each state of a tab – focused and non-focused, pressed and not pressed.

You can see part of this in action in the image above. Try long pressing on a tab and you can see the tab’s background change to use the unselected-pressed drawable.

Again, HUGE thanks to Jeff Gilfelt and Jake Wharton for creating tools that make our lives easier. :)

I have pushed a new branch in github that uses this style. The master branch of that repo still uses the default tab selectors.

2 min read

Quick Tip: Pulling an SQLite db file from device

I have always thought that you would need root access to pull an SQLite file from a non-rooted Android device. Turns out I thought wrong! Here’s how you do it:
<pre class="brush:shell">$ adb -d shell
$ run-as your.package.name
$ cat /data/data/your.package.name/databases/yourdatabasename >/sdcard/yourdatabasename</pre>This will copy your app’s SQLite db file to the SD card’s root directory. From there, you can copy the file to your computer any way you like.

Props to this SO answer!

~1 min read

I Can Haz Internetz!

Last week, I was exploring connectivity monitoring and came up with a small app for demo. The app listens for connectivity changes and sends a notification to the user informing them of the change.

First off, create a class (I named mine ConnectivityUpdate.java) and make it extend BroadcastReceiver. This class should do what you want when notified of connectivity changes. You will be asked to implement the onReceive() method. Now here’s what I want to happen when the system notifies me of changes:
1. Check what kind of change I am being notified of: did I get Internet? Or did I lose Internet?
2. Compare this to what connectivity I had before the notification so I can inform the user (and app-wise do whatever it is I’m supposed to do like start syncing or stop syncing).

In my implementation, this is done as:
<pre class="brush:java">@Override
public void onReceive(Context context, Intent intent) {

boolean hasInternet = false;
Log.d(LOG_TAG, “Received broadcast!”);

// Do I have Internet?
if(intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
hasInternet = (new NDUtils()).hasInternet(context);
}

// Did I use to have Internet?
SharedPrefsManager prefs = new SharedPrefsManager();
boolean prevValue = prefs.hasNetwork(context);

if(prevValue != hasInternet){
// Remember what we have now
(new SharedPrefsManager()).saveNetworkState(context, hasInternet);
sendNotification(hasInternet, context);
}
}
</pre>
The actual checking if we have Internet or not is done by a utility class: <pre class="brush:java">public boolean hasInternet(Context context){
NetworkInfo networkInfo = (NetworkInfo) ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();

// Check if we are connected to Wifi or mobile internet
// AND if we can actually send data
if(networkInfo!=null &&
(networkInfo.getType() == ConnectivityManager.TYPE_WIFI
  networkInfo.getType() == ConnectivityManager.TYPE_MOBILE)
&& networkInfo.isConnected()) {
return true;
}

return false;
}
</pre>
The Android javadoc on getActiveNetworkInfo() says it may return null, so we check first to avoid NullPointerExceptions, then we check if we have WiFi or mobile internet, THEN (and this is important) we check if we can send data through this network.

You can also refine this filter more by checking the type of mobile network the user has (we want 3G or faster) or by checking if the user is roaming (user should not be roaming). Here is a more complete method describing what I just said:<pre class="brush:java">public boolean hasInternet(Context context){
NetworkInfo networkInfo = (NetworkInfo) ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if(networkInfo!=null && networkInfo.isConnected() &&
(networkInfo.getType() == ConnectivityManager.TYPE_WIFI
 
(networkInfo.getType() == ConnectivityManager.TYPE_MOBILE && networkInfo.getSubtype() > TelephonyManager.NETWORK_TYPE_UMTS &&
!telephony.isNetworkRoaming()))) {

return true;
}

return false;
}</pre>
I then compare the returned value of the utility method to the last value saved in my preferences file. That part of the code is straight up saving/getting a boolean value from a SharedPreferences file.

I then inform the user of the network change through a notification. When the user clicks on the expanded notification, I want to open the app. The app can then display details about the network, but right now what my sample app does is simply show the boolean value returned by the utility method. Anyway, here’s how I send the notification:
<pre class="brush:java">private void sendNotification(boolean hasInternet, Context context) {
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);

// The notification details seen by the user when the drawer is pulled down
String notificationTitle = “Change in data connection!”;
String notificationText = “We have internet?: “ + (hasInternet ? “YES!” : “NO :(“);

// The icon and the text to be displayed in the notification area
Notification myNotification = new Notification(R.drawable.ic_launcher, “Broadcast received!”, System.currentTimeMillis());

// Create a new intent to launch my app
Intent myIntent = new Intent(context.getApplicationContext(), NetworkDetector.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context.getApplicationContext(), 0, myIntent, Intent.FLAG_ACTIVITY_NEW_TASK);

// Send that notification! MY_NOTIFICATION_ID is a value greater than 0.
myNotification.setLatestEventInfo(context,
notificationTitle,
notificationText,
pendingIntent);
notificationManager.notify(MY_NOTIFICATION_ID, myNotification);
}</pre>
So how do we tell the OS that we have made this receiver and please notify us when the connectivity changes, Mister Android please? We create a broadcast receiver in the app’s manifest! We listen to both CONNECTIVITY_CHANGE and WiFi STATE_CHANGE. The value for android:name is the name of the class containing the receiver implementation.
<pre class="brush:xml"><receiver
android:name=”.util.ConnectivityUpdate”
android:enabled=”true”
android:exported=”true”
android:label=”ConnectivityActionReceiver” >
<intent-filter>
<action android:name=”android.net.conn.CONNECTIVITY_CHANGE” />
<action android:name=”android.net.wifi.STATE_CHANGE” />
</intent-filter>
</receiver></pre>
And don’t forget to add the permissions to read the network state:
<pre class="brush:xml"><uses-permission android:name=”android.permission.ACCESS_WIFI_STATE” />
<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” /></pre>
<div>The complete source code for this sample app is in github.</div>
3 min read

Making ActionBarSherlock and ViewPagerIndicator play nice

EDIT (20121227): I made a new post on changing the tab selector underline.
EDIT (20121014): I received feedback from the comments that rotating the device will cause the tab contents to revert to the default text. In essence, the adapter “loses” the contents of the tabs. I have corrected this in the example below as well as in github.
EDIT (20120905): The full sample source code is now in github.

So ViewPagerIndicator cheerfully claims that it works with ActionBarSherlock. I was trying to test this out today and I can’t find a noob-friendly, step-by-step tutorial on how I can do it. I spent almost half a day frantically opening tab after tab in Google Chrome, but nothing seems to straight out say what I should do. So here it is, collated from several StackOverflow answers, blog posts, etc.

Get the ViewPagerIndicator (hereafter referred to as VPI) and ActionBarSherlock (hereafter referred to as ABS) libraries. Create your Android application in Eclipse and add those two projects as dependency library projects. If you do not know how to do that, see here.

First, create a theme. This is required by ABS, and will also help in VPI. What I did was to make the VPI theme inherit from the ABS theme so I don’t lose any of the styles I use in other parts of the app. I just add or override items needed by the ViewPagerIndicator. In this example, I just changed the text size and color of the tab labels. You can go one step further and change the selected tab indicator (via state selectors), change how the selectors are drawn, etc.
<pre class="brush:xml"><resources xmlns:android=”http://schemas.android.com/apk/res/android”>
<!– This is our main ActionBarSherlock theme –>
<style name=”Theme.Styled” parent=”Theme.Sherlock.Light.DarkActionBar”>
<item name=”actionBarStyle”>@style/Widget.Styled.ActionBar</item>
<item name=”android:actionBarStyle”>@style/Widget.Styled.ActionBar</item>
</style><!– This is our ViewPagerIndicator theme. We inherit from the ABS theme –>
<style name=”Theme.VPI” parent=”Theme.Styled”>
<item name=”vpiTabPageIndicatorStyle”>@style/CustomTabPageIndicator</item>
</style>  
<!– “Implementation” of our ABS custom theme –>
<style name=”Widget.Styled.ActionBar” parent=”Widget.Sherlock.Light.ActionBar.Solid.Inverse”>
<item name=”titleTextStyle”>@style/TitleText</item>
<item name=”android:titleTextStyle”>@style/TitleText</item>
</style>

<!– “Implementation” of VPI theme. We just set the text size and color. –>
<style name=”CustomTabPageIndicator” parent=”Widget.TabPageIndicator”>
<item name=”android:textSize”>50dip</item>
<item name=”android:textColor”>#FFB33E3E</item>
</style>

<!– More customizations for ABS –>
<style name=”TitleText” >
<item name=”android:textColor”>@android:color/darker_gray</item>
<item name=”android:textSize”>17dip</item>
</style>
</resources></pre>
Then we create the fragment(s) we need to populate the viewpager. My fragment is a simple layout with just a TextView indicating which tab is being shown.
<pre class="brush:java">public class TestFragment extends SherlockFragment {
private String mContent = “???”;

public static TestFragment newInstance(String text) {
TestFragment fragment = new TestFragment();

// Supply num input as an argument.
Bundle args = new Bundle();
args.putString(KEY_TAB_NUM, text);
fragment.setArguments(args);

return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, null);
String text = getString(R.string.tab_page_num) + mContent;
((TextView)view.findViewById(R.id.text)).setText(text);

return view;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContent = getArguments() != null ? getArguments().getString(KEY_TAB_NUM) : “???”;
}

}</pre>
Then we create the activity that will hold everything together.
<pre class="brush:java">public class VpiAbsTestActivity extends SherlockFragmentActivity {

private static final String[] TAB_TITLES = new String[] { “This”, “Is”, “A”, “ViewPager” };

TestFragmentAdapter mAdapter;
ViewPager mPager;
PageIndicator mIndicator;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.simple_tabs);

mAdapter = new TestFragmentAdapter(getSupportFragmentManager());

mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);

mIndicator = (TabPageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}

class TestFragmentAdapter extends FragmentPagerAdapter {
private int mCount = TAB_TITLES.length;

public TestFragmentAdapter(FragmentManager fm) {
super(fm);
}

@Override
public Fragment getItem(int position) {
return TestFragment.newInstance(String.valueOf(position));
}

@Override
public int getCount() {
return mCount;
}

@Override
public CharSequence getPageTitle(int position) {
return TAB_TITLES[position];
}
}
}</pre>And lastly, we apply the ViewPagerIndicator theme to our activity in the manifest:
<pre class="brush:xml"><activity android:name=”VpiAbsTestActivity” android:theme=”@style/Theme.VPI”>
</activity></pre>
As it turns out, it IS pretty straightforward!

2 min read

Save Logcat contents to file

Note to self: to save the contents of Logcat to a text file:
<ol><li>Navigate to the SDK installation directory.</li><li>Go to the /platform-tools folder.</li><li>adb logcat -d > my_logcat_dump.txt</li></ol><div>If there is more than one device connected to adb, specify which device’s log to dump:</div><div><blockquote class="tr_bq">adb -s emulator-5558 logcat -d > my_logcat_dump.txt</blockquote></div>

~1 min read

Cloning a remote branch in git

My current project at work uses git, and I have always been a CVS/SVN baby so I’m still trying to find my way around it. Today I wanted to clone a remote branch to my local computer. This remote branch also has submodules, so I want to get those too.

This assumes that you use Git Bash. First, navigate to the folder in you local computer where you want git to clone the remote branch. Once there, we can start cloning the repo. The following steps do the dirty work:
<pre class="brush:bash">$ git init
$ git fetch <git url> <branch name>:refs/remotes/origin/<branch name>
$ git checkout -b <branch name> origin/<branch name></pre>
This retrieves the contents of the remote branch and copies it to our local computer in a local branch (confused yet?). To update our copy of the submodules, the following commands should work:
<pre class="brush:bash">$ git submodule init
$ git submodule update</pre>

~1 min read