Post Reply

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

10th June 2012, 09:03 PM   |  #1  
Chris95X8's Avatar
OP Recognized Contributor
Thanks Meter: 2,289
 
2,774 posts
Join Date:Joined: Mar 2011
More
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, 1177 views)
Last edited by Chris95X8; 15th February 2013 at 08:09 PM.
The Following 45 Users Say Thank You to Chris95X8 For This Useful Post: [ View ]
10th June 2012, 09:54 PM   |  #2  
wilbso's Avatar
Senior Member
Flag The Internet
Thanks Meter: 245
 
1,369 posts
Join Date:Joined: Aug 2011
Donate to Me
More
Exelent guide buddy
Another score for successful guides

W!LSO @ XDA
10th June 2012, 09:54 PM   |  #3  
- Swift -'s Avatar
Recognized Contributor
Flag Galway, Ireland
Thanks Meter: 800
 
2,856 posts
Join Date:Joined: Sep 2011
Donate to Me
More
Thanks Chris.
Will come in handy.


-----------------
- Swift -, formerly known as IrishStuff09
10th June 2012, 11:38 PM   |  #4  
dimitrisioa's Avatar
Senior Member
Flag Macedonia Greece
Thanks Meter: 26
 
135 posts
Join Date:Joined: Mar 2011
More
Thank you Chris !

Sent from my X8 using xda premium
The Following User Says Thank You to dimitrisioa For This Useful Post: [ View ]
5th July 2012, 02:03 PM   |  #5  
Cancar96's Avatar
Senior Member
Flag Zagreb
Thanks Meter: 379
 
1,076 posts
Join Date:Joined: Sep 2011
More
great tutorial buddy!
getting right to do the job!
5th July 2012, 02:08 PM   |  #6  
Xmaster8's Avatar
Senior Member
Flag Ljutomer
Thanks Meter: 527
 
774 posts
Join Date:Joined: Nov 2011
More
I made one sometime ago but all ended when started to add settings
Anything didnt work anymore from then on
The Following User Says Thank You to Xmaster8 For This Useful Post: [ View ]
5th July 2012, 02:08 PM   |  #7  
AndroidExpert04's Avatar
Junior Member
Thanks Meter: 0
 
25 posts
Join Date:Joined: Jul 2012
Lol interesting, thanks.
14th October 2012, 06:50 PM   |  #8  
estherath's Avatar
Member
Thanks Meter: 9
 
36 posts
Join Date:Joined: Oct 2012
Too fun ! Thank you dude !
31st October 2012, 04:07 AM   |  #9  
Junior Member
Thanks Meter: 1
 
6 posts
Join Date:Joined: 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
31st October 2012, 08:28 PM   |  #10  
samsoul16's Avatar
Senior Member
Flag Thane
Thanks Meter: 519
 
1,361 posts
Join Date:Joined: Apr 2012
More
Quote:
Originally Posted by Chris95X8

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

Post Reply Subscribe to Thread

Tags
analog, clock, howto
Previous Thread Next Thread
Thread Tools
Display Modes


Top Threads in XPERIA X8 Themes and Apps by ThreadRank