Archive

Posts Tagged ‘androiddev’

Introducing SectionedActionBarList

November 27, 2014 2 comments

This Android library allows you to replace the drop down navigation list with a custom list where the items in the list are grouped by sections. It was inspired from the Google I/O 2014 app how sessions are grouped in the ActionBar list.

While the new Material Design movement discourages the use of ActionBar lists, in some situations it can be the best available option.

At the moment the library is not available on a repository, you have to include it as a source library in your project, but that will be fixed soon.

Github project page: https://github.com/vgrec/SectionedActionBarList

Example
List<Section> sections = new ArrayList<Section>();
 
Section themes = new Section("Themes");
themes.add("Design");
themes.add("Develop");
themes.add("Distribute");
sections.add(themes);
 
Section topics = new Section("Topics");
topics.add("Android");
topics.add("Chrome / Web");
topics.add("Cloud Services");
topics.add("Media");
topics.add("Location");
topics.add("Performance");
sections.add(topics);
 
Section types = new Section("Types");
types.add("Sessions");
types.add("App Reviews");
types.add("Box Talks");
sections.add(topics);
 
SectionedActionBarList actionBarList = new SectionedActionBarList(this).from(sections);
actionBarList.setItemSelectedListener(new ItemSelectedListener() {
  @Override
  public void onItemSelected(AdapterView<?> parent, View view, int position, long id, String sectionName, String itemName) {
      Toast.makeText(MainActivity.this, "Section: " + sectionName + ", Item: " + itemName, Toast.LENGTH_LONG).show();
  }
});

The SectionedActionBarList accepts a list of sections List<Section> sections, and every Section has a name and some associated items.

sectioned actionbar list

Configuration

Small customizations can be done to fit with your application design:

ListConfiguration configuration = new ListConfiguration(this);
configuration.setActionBarItemColorResource(R.color.brown);
configuration.setIndicatorDrawableResource(R.drawable.spinner_indicator_dark);
configuration.setSectionTitleColorResource(R.color.teal);
configuration.setDropdownItemColorResources(R.color.light_blue, R.color.dark_grey);

SectionedActionBarSpinner actionBarSpinner = new SectionedActionBarSpinner(this, configuration).from(sections);
// ....

actionbar list

Analysing Android code with SonarQube

May 29, 2014 3 comments

sonar analysis

SonarQube, formerly known as Sonar, is a platform to analyze code quality. Analysis covers such aspects as code duplications, potential bugs, coding rules, complexity, unit tests, comments, and architecture & design.
It supports supports more than 20 programming languages and has a reach set of useful plugins that gives you the opportunity to inspect different aspects of the code.

What is caracteristic about SonarQube is that it comes as a platform in the form of a web application. This means that the results of the analysis will be displayed in a web page.

Installing SonarQube

The installation is pretty straightforward, you have just to download an archive and extract it in a folder of your choice.
1. Go to http://www.sonarqube.org/downloads/ and download the latest release.
2. Unzip the archive

Starting SonarQube

1. Go to sonarqube-4.3/bin (or whatever version you downloaded)
2. Open a corresponding folder according to your operating system (linux-x86-64 in my case). There you should see a file called sonar.sh (or StartSonar.bat for Windows)
3. Open up a terminal window and execute: sonar.sh start (or just double click StartSonar.bat on windows). This command will start sonar listening on localhost:9000.
4. Open a browser and enter localhost:9000. The sonar web page should open.
Note that it may take some time until sonar loads, so if you get “page not found” in your browser, try to refresh the page later.

Installing SonarQube Runner

There are several ways to analyse the source code and in this tutorial we will choose to analyse with SonarQube Runner, recommended as the default launcher to analyze a project.

1. Once again go to http://www.sonarqube.org/downloads/ and download SonarQube Runner
2. Extract the downloaded archive into a directory of your choise, which we will refer as: <install_directory>
3. Update global settings by editing: <install_directory>/conf/sonar-runner.properties (if you are running sonar on localhost, like in this tutorial, you don’t have to modify any settings):

#----- Default SonarQube server
#sonar.host.url=http://localhost:9000

#----- PostgreSQL
#sonar.jdbc.url=jdbc:postgresql://localhost/sonar

#----- MySQL
#sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8

#----- Oracle
#sonar.jdbc.url=jdbc:oracle:thin:@localhost/XE

#----- Oracle
#sonar.jdbc.url=jdbc:oracle:thin:@localhost/XE

#----- Microsoft SQLServer
#sonar.jdbc.url=jdbc:jtds:sqlserver://localhost/sonar;SelectMethod=Cursor

#----- Global database settings
#sonar.jdbc.username=sonar
#sonar.jdbc.password=sonar

4. Create a new SONAR_RUNNER_HOME environment variable set to <install_directory>, so that you could invoke sonar runner from any location.
5. Add the <install_directory>/bin directory to your path.

To check that sonar runner was installed properly, open a terminal window and execute sonar-runner -h.

You should get a message like this:

usage: sonar-runner [options]

Options:
-D,--define Define property
-e,--errors Produce execution error messages
-h,--help Display help information
-v,--version Display version information
-X,--debug Produce execution debug output

Analysing source code of a project

Once the sonar runner is properly installed, we can proceed to code analysis.

1. Navigate to the root directory of your project and create a file called sonar-project.properties, which will specify the project settings such as the code source directory, language used, and the project name:

sonar.projectKey=myproject
sonar.projectName=My Project
sonar.projectVersion=1.0

sonar.sources=src
sonar.language=java
sonar.sourceEncoding=UTF-8

Note: for Android Studio, which follows the gradle directory structure, set the sourses as:

sonar.sources=src/main/java

2. Run sonar-runner command to start the analysis.
3. Once the analysis complets, head to localhost:9000 to see the results for your project.

Removing a project from SonarQube

First login as an administrator, admin/admin default username and password.

1. Go to your project dashboard
2. In the top right corner click on Configuration -> Deletion -> Delete Project

delete-shonar-project

Introducing Photo Collage Creator

February 27, 2014 7 comments

I was playing with bitmap manipulations and so was born the idea to make this app. It was started some time ago, and, even if at times I was thinking it will never see the daylight, finally it was released!

Description of the app:
Photo Collage Creator is a simple app that lets you create beautiful collages within seconds and share them with your family, friends or colleagues. To create a collage you just need to select the photos, apply the frames, save, and you are done!

Features:
– Create collages composed from up to 5 photos
– Various frames to create a collage
– Shuffle the photos within the collage
– Save your collages
– Share collages on gmail, facebook, picasa, and other social networking sites.

Hope you will like it!

collage maker

photo collage creator android

application on android market

Google Maps API V2 Android Tutorial

September 29, 2013 5 comments

In this tutorial we will walk through the process of integrating Google Maps API V2 into an Android project.

(Source code available on GitHub)

Android Google Maps API V2

The necessary steps in order to integrate the Google Maps V2 are :

1. Install Google Play services

The version 2 of Google Maps now is part of the Google Play services SDK, that is why google-play-services lib should be installed first.

Start the Android SDK Manager and choose to install Google Play services from the Extras category:
android sdk manager

After the sdk manager completes the installation, go to <android_sdk_folder>/extras/google/google_play_services/libproject and copy the google-play-services_lib to the location where you maintain your Android projects.

Then import the library project into your workspace, and reference it in your Android project.

2. Get the Google Maps API Key

In order to use Google Maps API in your project you need a valid Google Maps API key. The key can be obtained via the Google APIs Console. You will have to provide the SHA-1 fingerprint and the package name of your application.

Please note that if you already hold a map key from the Google Maps Android V1, also known as MapView, you still will need get a new API key, as the old key won’t work with the V2 API.

2.1 Generate SHA-1 certificate fingerprint

To display the SHA-1 fingerprint, first you need to decide for what type of certificate do you need to generate the fingerprint: for the debug certificate, or for the release certificate.
In this example we well consider displaying the fingerprint for the debug certificate.

The file name of debug certificate is called debug.keystore, and it is located on C:\Users\your_user_name\.android\ on Windows, and on ~/.android/ on Linux.

If you are on a Linux, open the terminal and run the following command:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

If you are on a Windows, open the command prompt and run this:
keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android

Copy the SHA1 fingerprint and store it somewhere for later use.
android sha1 certificate fingerprint

(Note that if the command prompt complains that keytool is not a recognizable command, you can find it your java JDK/bin folder. cd there and run the command from that folder.)

2.2 Create an API Project

Navigate to Google APIs Console and create a new project, if you haven’t used Google APIs Console before. Then click on the Services link from the left menu:
google services

and from the presented list of of services toggle Google Maps Android API V2:
google maps android api v2

(Please make sure you namely select “Google Maps Android API V2″, not Google Maps API v2, nor Google Maps API v3)

2.3 Obtain an API Key

a) From the left menu click on API Access
b) Then click on Create New Android Key
c) In the resulting dialog, enter the SHA-1 fingerprint, followed by a semicolon, and then your application package name.
For example:
95:F7:64:E9:3D:D44:70:EF:CB:F9:D9:14:BF:72:88:B4:E8:D7:11:E9;com.example.mapsv2

As a result the page displays a new section entitled Key for Android apps (with certificates), followed by your API key that looks something like this:
AIzaZyAcQKLEyHsamGpNLHdn8wd5-wuCqBnJ3Rk

2.4 Add the API key to AndroidManifest file

Open the AndroidManifest file and add the following element as a child of application tag:

<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="YOUR_API_KEY"/>

replacing the YOUR_API_KEY with your real API key.

3. Update the AndroidManifest file with other settings

In order to use Google Maps Android API we need to declare a few permissions and specify that the application requires OpenGL ES version 2:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    //... >

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
    //...
</manifest>
4. Display a MapFragment

Displaying the maps is as simple as declaring a fragment in the xml layout with the name com.google.android.gms.maps.MapFragment.
If you would like to make your application compatible with older devices, then you’ll have to use the Android Support Library and reference SupportMapFragment instead of MapFragment. The below example uses the Android Support Library.

The activity_main.xml layout:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/maps_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.google.android.gms.maps.SupportMapFragment" />

and the MainActivity.java:

public class MainActivity extends FragmentActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
}

If everything was configured correctly, then when running this example you should see a map.

Full source code can be downloaded from GitHub: https://github.com/vgrec/MapsV2Example

Example using ViewPager with ActionBarSherlock tabs

August 21, 2013 5 comments

In this post I’m going to show you an example usage of ViewPager in conjunction with ActionBarSherlock tabs.
The final result should look like this:

ActionBar with ViewPager

1. Add the ActionBarSherlock library to your project. (Here’s a short tutorial on how to integrate ABS with a project, in case you need a refresh on this)

2. Change the AndroidManifest file of your project to use one of the predefined themes by ABS:

<application       
        //....
        android:theme="@style/Theme.Sherlock.Light" >
        //.....
</application>

Note that using ActionBarSherlock requires you to use one of these themes: Theme.Sherlock, Theme.Sherlock.Light, Theme.Sherlock.Light.DarkActionBar, or any other derivate, otherwise a RuntimeException exception will be thrown.

3. Create the MainActivity.java:

public class MainActivity extends SherlockFragmentActivity {

	private ActionBar actionBar;
	private ViewPager viewPager;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		viewPager = (ViewPager) findViewById(R.id.pager);
		viewPager.setOnPageChangeListener(onPageChangeListener);
		viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
		addActionBarTabs();
	}

	private ViewPager.SimpleOnPageChangeListener onPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
		@Override
		public void onPageSelected(int position) {
			super.onPageSelected(position);
			actionBar.setSelectedNavigationItem(position);
		}
	};

	private void addActionBarTabs() {
		actionBar = getSupportActionBar();
		String[] tabs = { "Tab 1", "Tab 2", "Tab 3" };
		for (String tabTitle : tabs) {
			ActionBar.Tab tab = actionBar.newTab().setText(tabTitle)
					.setTabListener(tabListener);
			actionBar.addTab(tab);
		}
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
	}

	private ActionBar.TabListener tabListener = new ActionBar.TabListener() {
		@Override
		public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
			viewPager.setCurrentItem(tab.getPosition());
		}

		@Override
		public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
		}

		@Override
		public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
		}
	};
}

Another requirement in order to use Sherlock library is that your activity should extend from SherlockFragmentActivity, and this is what MainActivity does first.
Then it takes a reference to the ViewPager and sets the OnPageChangedListener and the PagerAdapter (implementation will be shown below):

viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setOnPageChangeListener(onPageChangeListener);
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));

In short, a ViewPager is a layout manager that allows you to swipe left and right through pages of data.
It needs to be supplied with an implementation of PagerAdapter in order to generate the pages that the view shows.

Just below the initialization of ViewPager the action bar tabs are added:

private void addActionBarTabs() {
	actionBar = getSupportActionBar();
	String[] tabs = { "Tab 1", "Tab 2", "Tab 3" };
	for (String tabTitle : tabs) {
		ActionBar.Tab tab = actionBar.newTab().setText(tabTitle)
				.setTabListener(tabListener);
		actionBar.addTab(tab);
	}
	actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
}

For every string in the tabs[] array a new ActionBar.Tab is created and added to the ActionBar.

4. And the layout of MainActivity, R.layout.activity_main, which simply defines the ViewPager container.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

5. The implementation of ViewPagerAdapter.java:

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

    private final int PAGES = 3;

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

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new TabFragment1();
            case 1:
                return new TabFragment2();
            case 2:
                return new TabFragment3();
            default:
                throw new IllegalArgumentException("The item position should be less or equal to:" + PAGES);
        }
    }

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

The PagerAdapter helps represent each page as a Fragment.
By extending FragmentStatePagerAdapter two methods should be overrided:
getCount() – which returns the total number of pages the ViewPager will have, and
getItem() – which returns a new fragment for each page.

6. Bellow follows the fragment classes used for representing each page. The minimalistic implementation is to extend from SherlockFragment, and provide a view for the fragment itself.
TabFragment1.java:

public class TabFragment1 extends SherlockFragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_tab_1, container, false);
	}
}

TabFragment2.java:

public class TabFragment2 extends SherlockFragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_tab_2, container, false);
	}
}

TabFragment3.java:

public class TabFragment3 extends SherlockFragment {
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_tab_3, container, false);
	}
}

7. And their corresponding layout files, which in this particular example have just a single TextView element.
fragment_tab_1.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment tab 1" />

</RelativeLayout>

fragment_tab_2.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment tab 2" />

</RelativeLayout>

fragment_tab_3.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment tab 3" />

</RelativeLayout>

Full project can be found on github: https://github.com/vgrec/SherlockActionBarTabs

Using Maven to save the build time in a properties file

Create a folder called build in the root directory of the project, and a file build.properties with the following content:

build.time=@buildtime@

Using the maven replacer plugin we can replace the token @buildtime@ within the build.properties file with the build timestamp value, and then let the Android application read that value and use it.

 
<plugins>
     <plugin>
         <groupId>com.google.code.maven-replacer-plugin</groupId>
         <artifactId>replacer</artifactId>
         <version>1.5.2</version>
         <executions>
            <execution>
               <phase>validate</phase>
               <goals>
                  <goal>replace</goal>
               </goals>
            </execution>
         </executions>
         <configuration>
            <file>build/build.properties</file>
               <outputFile>res/raw/build.properties</outputFile>
               <replacements>
                  <replacement>
                     <token>@buildtime@</token>
                     <value>${maven.build.timestamp}</value>
                  </replacement>
               </replacements>
        </configuration>
   </plugin>
</plugin>

Run this task with mvn validate command. This will do nothing but replace the tokens from build.properties file with the timestamp value, and output the result to a new file in res/raw.

From here on the file can be accessed as a raw resource and read as a regular properties file.

Reading the properties file:

InputStream rawResource = resources.openRawResource(R.raw.build);
Properties properties = new Properties();
properties.load(rawResource);
String buildTime = properties.getProperty("build.time");

Using Maven in Android to build for different environments (dev, staging, prod, etc)

July 18, 2013 4 comments

If you are working on a relatively complex project, chances are that you may need to build the application against different environments, such as a development, a staging, and a production environment. Assuming you are using Maven as a build tool, here’s one solution how Maven could help with this.

For the sake of this example let assume that you are working on an Android app that consumes web services. You have a dedicated development environment where you spent most of the time, but once every two weeks you need to make a version of the app that is built for production.

Let assume that the endpoint for the testing environment is dev.mysite.com, and for the production environment is: prod.mysite.com.
But as an aspiring developer and after reading a bunch of books about best practices, you can no longer accept to just go and manually edit the source files by changing all over the place one environment with another, and you ask yourself if Maven could help with this.

It can, and here’s how.
The main idea is to store all the properties, in this particular example all the urls, in separate resource files. Then, using maven resource plugin copy the corresponding property file into values/environment.xml.

1. In your project root directory create following directory structure:
environment/dev/environment.xml
environment/prod/environment.xml

maven environment

2. Then fill the content of the resource files with appropriate values.
/dev/environment.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="url">http://dev.mysite.com</string>
</resources>

/prod/environment.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="url">http://prod.mysite.com</string>
</resources>

3. Add the maven resource plugin to pom.xml by specifying the phase when the copy action should be executed, the resources, and the output directory:

//...
<plugins>
    <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.4.3</version>
        <executions>
             <execution>
                <id>copy-string-resources</id>
                <phase>validate</phase> <!-- when to execute copy operation -->
                <goals>
                    <goal>copy-resources</goal>
                </goals>
                <configuration>
                    <resources>
                        <resource>
                            <directory>environment/${environment}/</directory>
                            <includes>
                               <include>environment.xml</include>
                               <filtering>true</filtering>
                            </includes>
                        </resource>
                    </resources>
                    <overwrite>true</overwrite>
                    <outputDirectory>${basedir}/res/values/</outputDirectory>
                </configuration>
      </plugin>
</plugins>

4.1 From this point on, you can automate the preparation of environment by creating 2 run configurations:
mvn validate -Denvironment=dev
mvn validate -Denvironment=prod

that will do nothing but copy the appropriate resources from evironment/${environment}/environment.xml, into values/environment.xml

Now, every time you’ll need to prepare a build against a specific environment, the only thing you’ll need to do will be to run one of those commands.

4.2 Another option, to make the things even more compact, is instead of passing the environment like this: -Denvironment=dev, would be to create 2 profiles in pom.xml:

<profiles>
   <profile>
       <id>development</id>
       <properties>
           <environment>dev</environment>
       </properties>
   </profile>

   <profile>
       <id>prod</id>
       <properties>
           <environment>prod</environment>
       </properties>
   </profile>
</profiles>

and then create 2 run configurations with appropriate profile:
mvn validate -P development
mvn validate -P prod

For easy access at environment resources you could create a class like this that will return all the environment properties your applications uses:

public class ApplicationEnvironment{
	
	//...
	
	public String getServerUrl(){
		return resources.getString(R.string.url);
	}	
}
Follow

Get every new post delivered to your Inbox.

Join 545 other followers

%d bloggers like this: