Attend XDA's Second Annual Developer Conference, XDA:DevCon 2014!
5,784,212 Members 42,422 Now Online
XDA Developers Android and Mobile Development Forum

[HOWTO] Make your own analog clock | 10-Jun-12

Tip us?
 
Chris95X8
Old
(Last edited by Chris95X8; 15th February 2013 at 08:09 PM.)
#1  
Chris95X8's Avatar
Recognized Contributor - OP
Thanks Meter 2,289
Posts: 2,774
Join Date: Mar 2011
Default [HOWTO] Make your own analog clock | 10-Jun-12

Hello, this is Chris talking, your fellow Time Keeper (yeah, I was nicknamed) and this is my tutorial on how to build a simple, lightweight analog clock!

__________________________________________________ ____________

This guide assumes that you have successfully set up the Android SDK, ADT, Eclipse, some basic Java knowledge and image editing skills.
__________________________________________________ _____________
Let's start!

Go to the menu bar and click File > New > Android Project
Give your project a name, such as "XDA Devs Clock". Anything you prefer. This isn't going to affect the final app.

Next, select Android 1.6 as the build target. Analog clocks don't require anything special.

Now it's time to create the package name. I usually make mine like "com.xda.clock.chris".
Untick the "Create Activity" checkbox.

Info: We don't need to create an Activity because we are making a widget. Widgets don't have Activities, otherwise, they would be shown in the app drawer.

Click Finish and Eclipse will set up the project.



__________________________________________________ ______________

Next up, you need to make 3 images for the clock:
  • The dial (which is the clock's background)
  • The hour's hand
  • The minute's hand

Use your incredible Photoshop/GIMP/Illustrator skills to make your awesome clock!
Few tips:
  • Make the canvas 300*300 pixels
  • Make the dial with 10% padding
  • To easily make the hands, keep the dial background and draw the hour's and minute's hand as they were at position zero (Hour at 12 o'clock and minute at zero). Erase the dial and save each hand image
Save with a .png extension. So, in the end, you will have 3 images. Name them:
  • hand_dial.png
  • hand_minute.png
  • hand_hour.png

All lower case. It is extremely important or else you will get an error!

Also, create an app icon. You need to make 3 different ones for every screen size.
  • HDPI - 72*72 px
  • MDPI - 48*48 px
  • LDPI - 36*36 px

Save them with the name "ic_launcher.png" and overwrite the images that are already in the project's respective folders.



__________________________________________________ ______________

Following, we gotta put them to our app.
So, first, right-click res > New > New folder and name it "drawable".
Drag your images you created previously into there.

Now, let's make the layout of the clock.
Go to res > layout > main.xml

Go to the main.xml tab (at the bottom) and delete the TextView block. Next, change the layout from Linear to Relative.

Now, we will add the clock's code.
Code:
<AnalogClock
        android:id="@+id/analogClock1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" 

        android:dial="@drawable/hand_dial"
        android:hand_minute="@drawable/hand_minute"
        android:hand_hour="@drawable/hand_hour"/>
So, what did we do there?
  • We gave the item an id
  • We put it in the middle of the screen
  • We redirected the drawables to the respective hand and dial

The final xml is this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <AnalogClock
        android:id="@+id/analogClock1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" 
        android:dial="@drawable/hand_dial"
        android:hand_minute="@drawable/hand_minute"
        android:hand_hour="@drawable/hand_hour"/>

</RelativeLayout>
__________________________________________________ _____________


Next, we need to tell Android that what we are actually doing is a widget.

Right click res and create a folder named "xml".
Right clock xml > New > Android XML file

Change the Resource Type to AppWidgetProvider and give it a name such as "widget_config.xml". Lower case!

Delete everything and paste this in:
Code:
<appwidget-provider 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:minWidth="140dip" 
    android:minHeight="140dip" 
    android:updatePeriodMillis="0" 
    android:initialLayout="@layout/main"/>
There we set how many rows the widget will take. The calculation method is
74 * [number of rows] - 4

We want the widget to be 2*2 so the width is 146dip and the height is also 146dip. But we'll change it to 140 to make it a little bigger.

Then we set an update period... which actually doesn't work below 30 minutes. It's a bug in Android and last, we gave it a layout, which we made previously (main.xml).

__________________________________________________ __________

Now, we must declare the widget in the manifest.xml with a <receiver> element.

Open the manifest xml and delete the <activity> block. As said previously, we won't have any activity.

Inside the <application> add this piece of code:

Code:
<receiver android:name=".Clock_Actions" android:label="XDA Analog Clock">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_config" />
        </receiver>
The android:name is the class we are going to create in a few minutes.
The label is the name that will be shown in the widget picker of your homescreen. Then we specified the update and linked the widget_config.xml

The final xml is:
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xda.clock.chris"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        
        <receiver android:name=".Clock_Actions" android:label="XDA Analog Clock">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_config" />
        </receiver>
        
    </application>

</manifest>
__________________________________________________ _____________

Now it's time to create the Clock_Actions class.

Right click the package > New > Class
Give it the above name.

Delete everything and paste this in:
Code:
package com.xda.clock.chris;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.widget.RemoteViews;

public class Clock_Actions extends AppWidgetProvider{

	public void onReceive(Context context, Intent intent)
	{
		String action = intent.getAction();
		PendingIntent pendingIntent;
		if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action))
		{
			
			RemoteViews views = new RemoteViews(context.getPackageName(),
					R.layout.main);

			pendingIntent = PendingIntent.getActivity(context, 0,getAlarmPackage(context), 0);
			views.setOnClickPendingIntent(R.id.analogClock1, pendingIntent);

			AppWidgetManager
					.getInstance(context)
					.updateAppWidget(
							intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS),
							views);
		}
	}
	
	public Intent getAlarmPackage(Context context)
	{
		PackageManager packageManager = context.getPackageManager();
		Intent AlarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
		
		String clockImpls[][] = {
				{ "Standard Alarm", "com.android.alarmclock",
						"com.android.alarmclock.AlarmClock" },
				{ "HTC Alarm ClockDT", "com.htc.android.worldclock",
						"com.htc.android.worldclock.WorldClockTabControl" },
				{ "Standard Alarm ClockDT", "com.android.deskclock",
						"com.android.deskclock.AlarmClock" },
				{ "Froyo Nexus Alarm ClockDT",
						"com.google.android.deskclock",
						"com.android.deskclock.DeskClock" },
				{ "Moto Blur Alarm ClockDT",
						"com.motorola.blur.alarmclock",
						"com.motorola.blur.alarmclock.AlarmClock" },
				{ "Samsung Galaxy S", "com.sec.android.app.clockpackage",
						"com.sec.android.app.clockpackage.ClockPackage" } };

		boolean foundClockImpl = false;

		for (int i = 0; i < clockImpls.length; i++)
		{
			String packageName = clockImpls[i][1];
			String className = clockImpls[i][2];
			try
			{
				ComponentName cn = new ComponentName(packageName, className);
				packageManager.getActivityInfo(cn,PackageManager.GET_META_DATA);
				AlarmClockIntent.setComponent(cn);
				foundClockImpl = true;
			} catch (NameNotFoundException nf)
			{
			}
		}
		if (foundClockImpl)
		{
			return AlarmClockIntent;
		}
		else
		{
			return null;
		}
	}
}
Change the package name to your own after pasting.

So here, we set up the update, the remote views and the pending intent which redirects you to the Desk Clock app. Because different phones have different Desk Clock package names, we set up a method to handle that.
Many thanks to sndytime. Got the code from his post here.

__________________________________________________ __________

Next up...nothing! Our clock is done! We just have to export it.
Right click the project > Android tools > Export signed application

Choose next, select Create new keystore > click browse and give it a name.
Create a password and click next.

In alias put whatever you want. I usually put "chris95x8"
Enter your password again and put, like, 100 year for validity. You get the rest.

Click Next, browse and enter a name for the apk.
Click Finish and congrats on your first analog clock! Yay!

If you have done everything right it should work. Otherwise, comment here on the thread.

*Sorry for big images


__________________________________________________ ____________

I hope to see some clock on the Themes & Apps section soon. Good luck everyone!
Attached Files
File Type: apk XDA Devs Clock.apk - [Click for QR Code] (60.2 KB, 1144 views)
The Following 45 Users Say Thank You to Chris95X8 For This Useful Post: [ Click to Expand ]
 
wilbso
Old
#2  
wilbso's Avatar
Senior Member
Thanks Meter 243
Posts: 1,368
Join Date: Aug 2011
Location: The Internet

 
DONATE TO ME
Exelent guide buddy
Another score for successful guides

W!LSO @ XDA
Nice to be back.
 
- Swift -
Old
#3  
- Swift -'s Avatar
Recognized Contributor
Thanks Meter 800
Posts: 2,856
Join Date: Sep 2011
Location: Galway, Ireland

 
DONATE TO ME
Thanks Chris.
Will come in handy.


-----------------
- Swift -, formerly known as IrishStuff09
GOOGLE Nexus 4
GOOGLE Nexus 7 (2013)

---
Devices:
 
 
dimitrisioa
Old
#4  
dimitrisioa's Avatar
Senior Member
Thanks Meter 26
Posts: 135
Join Date: Mar 2011
Location: Macedonia Greece
Thank you Chris !

Sent from my X8 using xda premium
The Following User Says Thank You to dimitrisioa For This Useful Post: [ Click to Expand ]
 
Cancar96
Old
#5  
Cancar96's Avatar
Senior Member
Thanks Meter 378
Posts: 1,072
Join Date: Sep 2011
Location: Zagreb
great tutorial buddy!
getting right to do the job!
-----------------------------------------------------------------------------------------------------
My devices
 

XPERIA X8
android os 2.3.7
SDE v3.5
OC 729 MHz
nAa-14 kernel 2.6.29.6
XPERIA X8
android 2.3.7
gingerDX v30
stock SE kernel 2.6.29.6
Iphone 4s
iOS 7
 
Xmaster8
Old
#6  
Xmaster8's Avatar
Senior Member
Thanks Meter 526
Posts: 773
Join Date: Nov 2011
Location: Ljutomer
I made one sometime ago but all ended when started to add settings
Anything didnt work anymore from then on


Older devices: SE T290i, T700, Nokia 5320, Xperia X8
The Following User Says Thank You to Xmaster8 For This Useful Post: [ Click to Expand ]
 
AndroidExpert04
Old
#7  
AndroidExpert04's Avatar
Junior Member
Thanks Meter 0
Posts: 25
Join Date: Jul 2012
Lol interesting, thanks.
 
estherath
Old
#8  
estherath's Avatar
Member
Thanks Meter 9
Posts: 36
Join Date: Oct 2012
Too fun ! Thank you dude !
 
west1988
Old
#9  
Junior Member
Thanks Meter 1
Posts: 6
Join Date: Oct 2012
Great Job Chriss, nice and clear. However I still menaged to get stuck.

Quote:
Now it's time to create the Clock_Actions class.

Right click the package > New > Class

Where/what should I right click?

For now I created in in src folder in (default package), but I get 3 errors, so I assume I did it wrong.

Anyway tutorial looks great
 
samsoul16
Old
#10  
samsoul16's Avatar
Senior Member
Thanks Meter 519
Posts: 1,361
Join Date: Apr 2012
Location: Thane
Quote:
Originally Posted by Chris95X8 View Post
Hello, this is Chris talking, your fellow Time Keeper (yeah, I was nicknamed) and this is my tutorial on how to build a simple, lightweight analog clock!

__________________________________________________ ____________

This guide assumes that you have successfully set up the Android SDK, ADT, Eclipse, some basic Java knowledge and image editing skills.
__________________________________________________ _____________
Let's start!

Go to the menu bar and click File > New > Android Project
Give your project a name, such as "XDA Devs Clock". Anything you prefer. This isn't going to affect the final app.

Next, select Android 1.6 as the build target. Analog clocks don't require anything special.

Now it's time to create the package name. I usually make mine like "com.xda.clock.chris".
Untick the "Create Activity" checkbox.

Info: We don't need to create an Activity because we are making a widget. Widgets don't have Activities, otherwise, they would be shown in the app drawer.

Click Finish and Eclipse will set up the project.



__________________________________________________ ______________

Next up, you need to make 3 images for the clock:
  • The dial (which is the clock's background)
  • The hour's hand
  • The minute's hand

Use your incredible Photoshop/GIMP/Illustrator skills to make your awesome clock!
Few tips:
  • Make the canvas 300*300 pixels
  • Make the dial with 10% padding
  • To easily make the hands, keep the dial background and draw the hour's and minute's hand as they were at position zero (Hour at 12 o'clock and minute at zero). Erase the dial and save each hand image
Save with a .png extension. So, in the end, you will have 3 images. Name them:
  • hand_dial.png
  • hand_minute.png
  • hand_hour.png

All lower case. It is extremely important or else you will get an error!

Also, create an app icon. You need to make 3 different ones for every screen size.
  • HDPI - 72*72 px
  • MDPI - 48*48 px
  • LDPI - 36*36 px

Save them with the name "ic_launcher.png" and overwrite the images that are already in the project's respective folders.



__________________________________________________ ______________

Following, we gotta put them to our app.
So, first, right-click res > New > New folder and name it "drawable".
Drag your images you created previously into there.

Now, let's make the layout of the clock.
Go to res > layout > main.xml

Go to the main.xml tab (at the bottom) and delete the TextView block. Next, change the layout from Linear to Relative.

Now, we will add the clock's code.
Code:
<AnalogClock
        android:id="@+id/analogClock1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" 

        android:dial="@drawable/hand_dial"
        android:hand_minute="@drawable/hand_minute"
        android:hand_hour="@drawable/hand_hour"/>
So, what did we do there?
  • We gave the item an id
  • We put it in the middle of the screen
  • We redirected the drawables to the respective hand and dial

The final xml is this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <AnalogClock
        android:id="@+id/analogClock1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" 
        android:dial="@drawable/hand_dial"
        android:hand_minute="@drawable/hand_minute"
        android:hand_hour="@drawable/hand_hour"/>

</RelativeLayout>
__________________________________________________ _____________


Next, we need to tell Android that what we are actually doing is a widget.

Right click res and create a folder named "xml".
Right clock xml > New > Android XML file

Change the Resource Type to AppWidgetProvider and give it a name such as "widget_config.xml". Lower case!

Delete everything and paste this in:
Code:
<appwidget-provider 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:minWidth="146dip" 
    android:minHeight="146dip" 
    android:updatePeriodMillis="0" 
    android:initialLayout="@layout/main"/>
There we set how many rows the widget will take. The calculation method is
74 * [number of rows] - 4

We want the widget to be 2*2 so the width is 146dip and the height is also 146dip.

Then we set an update period... which actually doesn't work below 30 minutes. It's a bug in Android and last, we gave it a layout, which we made previously (main.xml).

__________________________________________________ __________

Now, we must declare the widget in the manifest.xml with a <receiver> element.

Open the manifest xml and delete the <activity> block. As said previously, we won't have any activity.

Inside the <application> add this piece of code:

Code:
<receiver android:name=".Clock_Actions" android:label="XDA Analog Clock">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_config" />
        </receiver>
The android:name is the class we are going to create in a few minutes.
The label is the name that will be shown in the widget picker of your homescreen. Then we specified the update and linked the widget_config.xml

The final xml is:
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xda.clock.chris"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        
        <receiver android:name=".Clock_Actions" android:label="XDA Analog Clock">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_config" />
        </receiver>
        
    </application>

</manifest>
__________________________________________________ _____________

Now it's time to create the Clock_Actions class.

Right click the package > New > Class
Give it the above name.

Delete everything and paste this in:
Code:
package com.xda.clock.chris;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.widget.RemoteViews;

public class Clock_Actions extends AppWidgetProvider{

public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
PendingIntent pendingIntent;
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action))
{

RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.main);

pendingIntent = PendingIntent.getActivity(context, 0,getAlarmPackage(context), 0);
views.setOnClickPendingIntent(R.id.analogClock1, pendingIntent);

AppWidgetManager
.getInstance(context)
.updateAppWidget(
intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS),
views);
}
}

public Intent getAlarmPackage(Context context)
{
PackageManager packageManager = context.getPackageManager();
Intent AlarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);

String clockImpls[][] = {
{ "Standard Alarm", "com.android.alarmclock",
"com.android.alarmclock.AlarmClock" },
{ "HTC Alarm ClockDT", "com.htc.android.worldclock",
"com.htc.android.worldclock.WorldClockTabControl" },
{ "Standard Alarm ClockDT", "com.android.deskclock",
"com.android.deskclock.AlarmClock" },
{ "Froyo Nexus Alarm ClockDT",
"com.google.android.deskclock",
"com.android.deskclock.DeskClock" },
{ "Moto Blur Alarm ClockDT",
"com.motorola.blur.alarmclock",
"com.motorola.blur.alarmclock.AlarmClock" },
{ "Samsung Galaxy S", "com.sec.android.app.clockpackage",
"com.sec.android.app.clockpackage.ClockPackage" } };

boolean foundClockImpl = false;

for (int i = 0; i < clockImpls.length; i++)
{
String packageName = clockImpls[i][1];
String className = clockImpls[i][2];
try
{
ComponentName cn = new ComponentName(packageName, className);
packageManager.getActivityInfo(cn,PackageManager.GET_META_DATA);
AlarmClockIntent.setComponent(cn);
foundClockImpl = true;
} catch (NameNotFoundException nf)
{
}
}
if (foundClockImpl)
{
return AlarmClockIntent;
}
else
{
return null;
}
}
}
Change the package name to your own after pasting.

So here, we set up the update, the remote views and the pending intent which redirects you to the Desk Clock app. Because different phones have different Desk Clock package names, we set up a method to handle that.
Many thanks to sndytime. Got the code from his post here.

__________________________________________________ __________

Next up...nothing! Our clock is done! We just have to export it.
Right click the project > Android tools > Export signed application

Choose next, select Create new keystore > click browse and give it a name.
Create a password and click next.

In alias put whatever you want. I usually put "chris95x8"
Enter your password again and put, like, 100 year for validity. You get the rest.

Click Next, browse and enter a name for the apk.
Click Finish and congrats on your first analog clock! Yay!

If you have done everything right it should work. Otherwise, comment here on the thread.

*Sorry for big images


__________________________________________________ ____________

I hope to see some clock on the Themes & Apps section soon. Good luck everyone!
U awe from me a thanks and a beer.. N1 bro.. :beer::thumbup:

Sent from my GT-S6102 using xda premium

Tags
analog, clock, howto
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes