Sunday, August 29, 2010

Creating shortcuts through Intent in Android

We can create shortcut for an application through intent. Its not so difficult. First create an intent with the package name of the application and add some flags to it. Then create another intent and add the first intent to it as extras and broadcast the intent. That is it.

The complete code is,



public class CreateShortcut extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent shortcutIntent = new Intent();
Log.i("CreateShortcut", "Creating first intent called shortcutIntent");
shortcutIntent.setClassName(getPackageName(), "CreateShortcut");
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Intent intent = new Intent();
Log.i("CreateShortcut", "Creating intent for broadcasting");
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "ShortcutName");
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, false);
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
sendBroadcast(intent);
}
}



Steps for launching the shortcut is,


-> Long press on the empty part of the home screen

-> Select "Shortcuts" from the dialog that pop-up




-> Select "Applications" from the dialog that pop-up





-> Select "CreateShortcut" from the dialog that pop-up





-> Now, we can see the shortcut for our application in home screen.

Creating LiveFolder in Android

In Android, a live folder is simply a real-time view of a ContentProvider. LiveFolder allow displaying of data on home screen without launching the application.



public class CreateLiveFolder extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri uri = Browser.BOOKMARKS_URI;
final Intent intent = getIntent();
final String action = intent.getAction();
if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
setResult(RESULT_OK, createLiveFolder(this, uri,
"Books", R.drawable.icon));
} else {
setResult(RESULT_CANCELED);
}
finish();
}

private static Intent createLiveFolder(Context context, Uri uri, String name, int icon) {
final Intent intent = new Intent();
intent.setData(uri);
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, name);
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON,
Intent.ShortcutIconResource.fromContext(context, icon));
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE, LiveFolders.DISPLAY_MODE_LIST);
return intent;
}
}



The manifest file will look like this,



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.createlivefolder" android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".CreateLiveFolder"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<intent-filter>
<action android:name="android.intent.action.CREATE_LIVE_FOLDER"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>



In this case, I don't have any bookmark in my browser, so an empty content provider is shown.


Steps to launch LiveFolder :


After launching the application
-> Long press on the empty space of the home screen
-> Select "Folder" from the dialog that pop-up



-> Select "CreateLiveFolder".





This will create the live folder in home screen in the name of "SampleLiveFolder".



The screenshots are,



When we click on the icon, our live folder called "SampleLiveFolder" will open. As my "bookmarks" in browser is empty, it will show an empty dialog box

Saturday, August 28, 2010

Opening Contacts, Gallery and other system applications through Intent in Android

Code snippets for opening contacts, gallery etc through intent


// opening Contact
Intent intent = new Intent(Intent.ACTION_PICK, People.CONTENT_URI);
startActivityForResult(intent, REQUEST_CODE);



               
// opening Gallery
Intent i = new Intent(Intent.ACTION_PICK);
i.setType("image/*");
startActivityForResult(i, 1);



// opening All
Intent i = new Intent(Intent.ACTION_PICK);
i.setType("*/*");
startActivityForResult(i, 1);


By setting the type of the intent object to image/*, gallery will display, accordingly if we put corresponding action and data , we can display SMS, settings page etc.

If we put the data of intent as "*/*", a pop-up will display, which shows the available list of the applications that can display.

The screen shot is,

Friday, August 6, 2010

Live Wallpaper in Android

Live wallpaper is richer, animated, interactive backgrounds on the home screen of Android devices. A live wallpaper is very similar to a normal Android application and has access to all the facilities of the platform: SGL (2D drawing), OpenGL (3D drawing), GPS, accelerometers, network access, etc.

A live wallpaper is very similar to a regular Android service. The only difference is the addition of a new method, onCreateEngine() whose goal is to create a WallpaperService.Engine. The engine is responsible for handling the lifecycle and the drawing of a wallpaper.

Here, I am showing a general method for creating Live Wallpaper. According to our requirement or to our wish, we can draw some image when we touch anywhere on the screen, or according to the time, we can set different images like for morning from 6AM to 12PM, then 12PM to 6PM another image like that. or according to the location, we can set some image. In office one image, in home, another image like that.

First thing for creating Live Wallpaper in android is, declare the service in manifest file.


<service android:label="@string/wallpaper_cube1"
android:name=".LiveWallpaper"
android:permission="android.permission.BIND_WALLPAPER">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data android:name="android.service.wallpaper" android:resource="@xml/livewallpaper" />
</service>


A file named "livewallpaper.xml" should be placed in res/xml, which should look like this as,


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


In the manifest file, we also need to put,


<uses-sdk android:minSdkVersion="7" />
<uses-feature android:name="android.software.live_wallpaper" />


Live Wallpaper is from 2.1 SDK onwards.


The implementation of the live LiveWallpaper.java is as,


public class LiveWallpaperService extends WallpaperService {

@Override
public Engine onCreateEngine() {
return new WallpaperEngine();
}

@Override
public void onCreate() {
super.onCreate();
}

@Override
public void onDestroy() {
super.onDestroy();
}
public class WallpaperEngine extends Engine {
private LiveWallpaperPainting painting;

WallpaperEngine () {
SurfaceHolder holder = getSurfaceHolder();
painting = new LiveWallpaperPainting(holder,
getApplicationContext());
}

@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
setTouchEventsEnabled(true);
}

@Override
public void onDestroy() {
super.onDestroy();
painting.stopPainting();
}

@Override
public void onVisibilityChanged(boolean visible) {
if (visible) {
painting.resumePainting();
} else {
painting.pausePainting();
}
}

@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
painting.setSurfaceSize(width, height);
}

@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
// start painting
painting.start();
}

@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
boolean retry = true;
painting.stopPainting();
while (retry) {
try {
painting.join();
retry = false;
} catch (InterruptedException e) {}
}
}

@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xStep, float yStep, int xPixels, int yPixels) {
}

@Override
public void onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
painting.doTouchEvent(event);
}
}
}



The "LiveWallpaperPainting .java" is as follows,


public class LiveWallpaperPainting extends Thread {

private SurfaceHolder surfaceHolder;
private Context context;

private boolean wait;
private boolean run;

private int width;
private int height;

private long previousTime;
private long currentTime;

public LiveWallpaperPainting(SurfaceHolder surfaceHolder,
Context context) {
this.surfaceHolder = surfaceHolder;
this.context = context;
this.wait = true;
}

public void pausePainting() {
this.wait = true;
synchronized(this) {
this.notify();
}
}

public void resumePainting() {
this.wait = false;
synchronized(this) {
this.notify();
}
}

public void stopPainting() {
this.run = false;
synchronized(this) {
this.notify();
}
}

@Override
public void run() {
this.run = true;
Canvas c = null;
while (run) {
try {
c = this.surfaceHolder.lockCanvas(null);
synchronized (this.surfaceHolder) {
currentTime = System.currentTimeMillis();
updatePhysics();
doDraw(c);
previousTime = currentTime;
}
} finally {
if (c != null) {
this.surfaceHolder.unlockCanvasAndPost(c);
}
}
synchronized (this) {
if (wait) {
try {
wait();
} catch (Exception e) {}
}
}
}
}

public void setSurfaceSize(int width, int height) {
this.width = width;
this.height = height;
synchronized(this) {
this.notify();
}
}

public void doTouchEvent(MotionEvent event) {
this.wait = false;
synchronized(this) {
notify();
}
}

private void doDraw(Canvas canvas) {}

private void updatePhysics() {
// if nothing was updated :
// this.wait = true;
}

}

Androidians