Android: complete widget tutorial (including source code)

Source code
Hereby I share my widget tutorial source code. Feel free to download.

1. Create widget layout
layout is defined as any other layout in Android app. My layout consists of just one button and one imageView (/res/layout/widget_demo.xml).

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_margin="5sp"
    android:background="@android:drawable/alert_dark_frame" >

    <ImageView
        android:id="@+id/widget_image"
        android:layout_width="110sp"
        android:layout_height="110sp"
        android:layout_gravity="center"
        android:src="@drawable/wordpress_icon" />

    <Button
        android:id="@+id/widget_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Change it!" />

</LinearLayout>

Please remember that views that can be used in widget layout are limited. It depends on android version you are developing for. Find out more here. Make sure that view that you are using is supported by target android SDK version.

2. Create App Widget Provider declaration
This is another xml file that tells android OS that this application has a widget (display your widget in OS widget list). Create it with wizard:
File → New → Android → Android XML File

Widget Provider creation wizard
Widget Provider creation wizard

Widget size should be defined in dp. Usually widget size is related to one icon size on desktop (74 x 74 dp). Size should be mutiplication of such blocks. It may be calculated using formula:
((Number of columns or rows)* 74)

Please remember however to leave some space for margins. My widget 
has width and height equal to two icon blocks (146 dp x 146 dp):

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
    android:initialLayout="@layout/widget_demo" 
    android:minHeight="146dp" 
    android:minWidth="146dp"
    android:updatePeriodMillis="1000000" 
    >
</appwidget-provider>

3. Create AppWidgetProvider onUpdate implementation
Create class extending AppWidgetProvider. It will be responsible for updating your widget while Android OS requests it (e.g. widget is shown to user).
Here you have to set button listener (as a PendingIntent, because RemoteViews supports only that way of communication)

public class MyWidgetProvider extends AppWidgetProvider {

 @Override
 public void onUpdate(Context context, AppWidgetManager appWidgetManager,
   int[] appWidgetIds) {

  RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_demo);
  remoteViews.setOnClickPendingIntent(R.id.widget_button, buildButtonPendingIntent(context));

  pushWidgetUpdate(context, remoteViews);
 }

 public static PendingIntent buildButtonPendingIntent(Context context) {
  Intent intent = new Intent();
     intent.setAction("pl.looksok.intent.action.CHANGE_PICTURE");
     return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
 }

 public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
  ComponentName myWidget = new ComponentName(context, MyWidgetProvider.class);
     AppWidgetManager manager = AppWidgetManager.getInstance(context);
     manager.updateAppWidget(myWidget, remoteViews);  
 }
}

In buildButtonPendingIntent I set that after widget button press the intent will be sent. So now… it is time to catch that intent in Broadcast Receiver and handle widget update.

4. Register MyWidgetProvider in AndroidManifest.xml
Add these lines in <application/> tag:

        <receiver android:name="MyWidgetProvider" >
            <intent-filter >
                <action 
                    android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/demo_widget_provider" />
        </receiver>

5. Create Broadcast Intent receiver
This will be called for pending intents updates. Widgets are built on RemoteViews (views that are managed by another process than your application). This is why they communicate with your app by PendingIntents.

public class MyWidgetIntentReceiver extends BroadcastReceiver {

 private static int clickCount = 0;

 @Override
 public void onReceive(Context context, Intent intent) {
  if(intent.getAction().equals("pl.looksok.intent.action.CHANGE_PICTURE")){
   updateWidgetPictureAndButtonListener(context);
  }
 }

 private void updateWidgetPictureAndButtonListener(Context context) {
  RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_demo);
  remoteViews.setImageViewResource(R.id.widget_image, getImageToSet());

  //REMEMBER TO ALWAYS REFRESH YOUR BUTTON CLICK LISTENERS!!!
  remoteViews.setOnClickPendingIntent(R.id.widget_button, MyWidgetProvider.buildButtonPendingIntent(context));

  MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(), remoteViews);
 }

 private int getImageToSet() {
  clickCount++;
  return clickCount % 2 == 0 ? R.drawable.me : R.drawable.wordpress_icon;
 }
}

WARNING!!!
Since you are creating RemoteViews from scratch in Broadcast Receiver (using constructor with new keyword), you must refresh widget layout from scratch. Mainly: refresh the button listeners pending intents. This will help you to avoid issues like this and that.

6. Register Broadcast Receiver in AndroidManifest.xml
Add the following lines in <application/> tag:

<receiver
    android:name="MyWidgetIntentReceiver"
    android:label="widgetBroadcastReceiver" >
    <intent-filter>
        <action android:name="pl.looksok.intent.action.CHANGE_PICTURE" />
    </intent-filter>

    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/demo_widget_provider" />
</receiver>

7. That’s all!
Download the source code and enjoy! Feel free to customize widget according to your needs!

Here you will find some another widget tutorial. Maybe it will also be useful for you

XCode on Windows: How to Develop for Mac or iOS on a PC

Would you like to develop software for Mac OS X or iOS? While it’s easy to develop apps for Linux and Windows on any platform, developing software for Mac requires a toolset called XCode, designed and built by Apple specifically for Mac OS X.
XCode is an incredibly powerful piece of software. Not only is it a complete toolset for developing Mac apps; it’s also an interface builder, testing application, and asset management toolkit.
In this simple guide, you’ll learn how to use XCode on Windows – something that’s normally impossible. All you’ll need is a Windows PC, a copy of Mac OS X, an Apple account, and an Internet connection.
Is this your first time using XCode? Learn how to program software for Mac and iOS with our 1 Hour XCode Introduction.

Installing a virtual PC application with Mac OS X

Since XCode only runs on Mac OS X, you’ll need to be able to simulate an installation of Mac OS X on Windows. This is surprisingly easy to do with virtualization software like VMWare or open source alternative VirtualBox.
For the purpose of this guide, we’ll be using VirtualBox. If you use a different virtual computer application, the process is much the same. Since VirtualBox is open source and free to use, it’s worth downloading it if you don’t already have a copy installed.
Have you never used VirtualBox before? Learn how to use this powerful virtual PC application by enrolling in our course, QuickStart! – Virtual Box. In addition to Mac OS X, VirtualBox can also be used to run Linux and other operating systems.
Running a virtual computer is quite a demanding process, and you’ll need to have a fairly powerful PC for it to operate successfully. You’ll also need a PC with hardware similar to that of a standard, Apple-constructed iMac, MacBook, or Mac Pro.
To successfully emulate a Mac using a Windows PC, you’ll need the following:
  • A Dual Core Intel processor
  • At least 2GB of RAM (4GB+ recommended)
  • Hardware Virtualization
Is your PC too weak to emulate a Mac properly? Learn how to build a powerful PC for gaming, app development, and more with our Learn How to Build a Computer course.
You’ll also need an installation disc for Mac OS X. You can purchase this online from the Apple Store or, if you already own a MacBook, iMac, or Mac Pro, you can use the install disc you received with your computer.
Once you’ve installed VirtualBox, open the application and choose to install Mac OS X Server 64 Bit. Provide the virtual computer with at least 2GB of RAM (if you have more than 8GB of RAM, choose 4GB+) and more than 30GB of hard disk space.
VirtualBox will automatically configure the operating system, but you’ll still need to make a few changes manually. Open the Settings menu and carry out the following changes:
  • On the System tab, uncheck Enable EFI
  • On the Processor tab, select at least two CPUs
  • On the Display tab, increase the video memory to at least 128MB

Installing Mac OS X and booting your virtual machine

Finally, you’ll need to download a Hackboot boot loader to install OS X. You can find a Hackboot install file by searching Google – in this case, you’ll need Hackboot 1 and Hackboot 2, as well as your OS X disc, to complete the installation.
Select your Hackboot 1 disc image, and then start the virtual machine. Your virtual machine will boot, and you’ll see an OS X screen. Using the menu at the bottom of the screen, launch the disc drive that contains your OS X installation disc.
From here, you’ll need to follow the installation instructions for Mac OS X. It takes several minutes to install the operating system. Once the process is finished, you’ll need to switch off your virtual machine and change your boot disc.
Reopen VirtualBox and, leaving all of your other settings the same, switch your boot disc from Hackboot 1 to Hackboot 2. You’ll boot into a screen with two icons. Select Mac OS X and press Enter to initiate the Mac OS X boot sequence.
During the Mac OS X configuration sequence, you’ll need to enter your Apple ID. This is necessary for downloading the XCode toolset later, so make sure you enter a valid Apple account when you configure your operating system.

Installing XCode on your Mac OS X virtual machine

Once you’ve configured your Mac OS X virtual machine, installing XCode is relatively easy. Before you install XCode, you’ll want to configure your virtual machine to your preferred resolution and settings using the System Preferences menu.
Is this your first time using Mac OS X? If you’re a PC user, finding your way around in the new interface can be a challenge. Enroll in Using Mac OS X for Windows Users to learn the basics of the OS X interface, from the Dock to features like Spotlight.
From here, installing XCode is simple. Open the App Store application from the dock and type XCode into the search bar. You might need to reenter your account details, or enter them for the first time if you didn’t do so during Mac OS X configuration.
Navigate to the XCode app and click Install Now to download it. If you don’t have an Apple account, you’ll need to create one in order to download the XCode toolset for your virtual machine.
XCode is quite a large application, and downloading it could take anywhere from a minute to several hours, depending on your Internet connection speed. Once your download is finished, open Applications and click XCode to launch the installer.
Once the installation process is complete, you’ll be able to use XCode within your virtual machine to program apps for Mac OS or iOS. You can also download other Mac apps to use on your virtual machine, although they may not run smoothly.

Developing iOS Apps and more using XCode

XCode is an incredibly powerful toolkit for app development. It’s also refreshingly easy to use, especially for developers accustomed to cumbersome and complicated programming software for PC.

Learn more about how to use XCode by reading our iOS programming tutorial. It’s a great overview of the XCode interface, the programming characteristics of iOS, and much more.