Archive

Posts Tagged ‘Android’

Wordcube feedback

March 11th, 2010 mat No comments

This page was created for feedback from users of wordcube available via the wordcube website or as an app for android phones (available in market). Filling in these polls and leaving feedback will help improve wordcube for everyone.

How often do you play wordcube?

View Results

Loading ... Loading ...

How hard do you think the targets are to achieve?

View Results

Loading ... Loading ...

How do you play wordcube?

View Results

Loading ... Loading ...

Do you play

View Results

Loading ... Loading ...

Would you like more wordcube polls

View Results

Loading ... Loading ...

Thanks for your feedback. Please post any bugs, suggestions, complaints or ideas below.

Categories: Android, web Tags: , ,

Supporting multiple phones and screensizes in your android applications

February 11th, 2010 mat 1 comment

When releasing an android application it is often desirable to release your application to the largest amount of users as possible. By developing an application with android 1.5 as the target, later versions are automatically supported (1.6, 2.0, and 2.1). However different screen-sizes were introduced with android 1.6 so by default an application will not support smaller screens (larger screens are automatically supported).

Android Versions Marketshare
The image below shows the current market share for the different version of android:

Android version percentages

Android version marketshare

Android Platform Percentage of Devices
1.1 0.3%
1.5 27.7%
1.6 54.2%
2.0 2.9%
2.0.1 14.8%

Devices with small screens include the following phones T-Mobile G1, Samsung I7500, and the HTC Tattoo. Unfortunately I cannot find any statistics regarding the percentage of small screen android users (if you can please let me know). However as the fix is very simple it seems stupid not to.

Which version of android are you using?

View Results

Loading ... Loading ...

What screen size are you running android on

View Results

Loading ... Loading ...

Adding Support
To add support for different screen sizes we need to add a supports-screens tag in our android_manifest.xml. This should look like the following:

  <supports-screens
          android:largeScreens="true"
          android:normalScreens="true"
          android:smallScreens="true"
          android:anyDensity="false" />

This tells android that the application should work on large, normal and small screens. Note that only setting small to false will prevent it from been visible in the market to small screened phones, for normal and large it will simply change the method of which android interprets the display of this application. anyDensity fix me

However in order to use the supports-screens tag the target of your application must be android 1.6 (or Sdk version 4). We can allow our program which is now targetted for android 1.6 still be avaliable for android 1.5 (Sdk version 3) by adding android:minSdkVersion=”3″ to our uses-sdk tag.

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

Now your application can be built for 1.6 supporting smaller screen sizes and still work on 1.5.

Demonstration
Below are screenshots from two AVD’s, one with a normal screen size, and one with a small screen size:

android small screen wordcube

small screen android AVD running wordcube

android medium screen wordcube

Medium screen android AVD running wordcube

Note: Eclipse bug
Unfortunately eclipse currently does not acknowledge minSdkVersion and will not give you the option to test your application in any android virtual devices (AVD’s), while this is not fixed you can manually install the package into your AVD. For this you need to know the name of your emulator instance, to do this first run the AVD and then use the followin command to find out the name.

$adb devices
List of devices attached
emulator-5554   device

So we can see that the emulator instance I need is called emulator-5554. We can now use adb to install a package into this emulator. The below example shows installing wordcubefree from the bin folder in my project to my AVD using adb.

adb -s emulator-5554 install ~/android/workspace/WordCubeFree/bin/WordCubeFree.apk
1019 KB/s (39683 bytes in 0.038s)
Can't dispatch DDM chunk 46454154: no handler defined
Can't dispatch DDM chunk 4d505251: no handler defined
        pkg: /data/local/tmp/WordCubeFree.apk
Success

Note that this will fail if the application is already installed and you will need to uninstall the application before using this command (if anyone knows a switch to force install or alternative method please let me know)

Going Further
It is possible to delve into this is more detail by providing layouts for small, medium and large screen sizes. This can be explored in more detail in the google dev support guide

Categories: Android Tags: , ,

Android: Using SVN with your app’s project (and eclipse)

February 11th, 2010 mat 3 comments

When creating any non-trivial program using a versioning system is essential, especially when working in part of a group. This guide aims to be a quick tutorial to the SVN (subversion) tool for versioning and how to use it with an android project.

Assumptions

  • You will need SVN installed on your computer. This can be done using your package manager or by the following command in ubuntu / debian based systems:

    sudo apt-get install subversion
  • You already have an SVN repository configured. If not please view a tutorial like this or if you have a nice webhost like me (thanks dreamhost :P ) there may be a simple tool to do this automatically for you in your panel.

Note
Don’t include the files inside /bin or /gen as they are just build from the source code and will simply fill up a lot space in your SVN. But do include the folders themselves as the project will fail to build without them.

Command line (recommended)
For SVN, I am a great fan of the command line. From the few SVN GUI applications that I have used in the past I can recommend Turtoise SVN for windows and kdesvn for linux (kde) but I still prefer the command line.

The following code will checkout the project from your server. This will create a new folder called “projectname” on your computer and download the project from your server (at this point it is most likely an empty folder).

# Checkout the SVN directory
svn co svn.yourdomain.com/projectname projectname

You can then copy or create your android project in this directory. In our project folder there are two folders which contain generated files (as opposed to source files) there is no point uploading these to the svn as you will simply take up space and bandwidth. Before you decided to upload your changes to the server you should empty the bin and gen folders:

# Empty bin and gen folders
rm -rf ./projectname/bin/*
rm -rf ./projectname/gen/*

Each time you add a new file to the project you will need to add (`svn add filename` for single files or `svn add *` for all files):

# Tell SVN we want to be versioning these files
svn add projectname/*

When you are happy with your changes you can commit (`svn commit -m “message”`) your changes to the svn to create a new version, it is mandatory to include a message with each revision and it is best to be as detailed as possible with the changes made. This makes it much easier to hunt down where a bug or regression was introduced.

# Save the changes and upload to repository
svn commit -m "Initial import of projectname"

Each time you commit or wish to upgrade what is stored locally to the latest version on the server you need to use the following:

# Update the locally stored version
svn update projectname

Further points
Eclipse has a plugin to manage SVN download and install instructions can be found here.

Categories: Android Tags: , , , , ,

How to tell android which volume (media/ringtone etc.) should be controlled by your app

February 1st, 2010 mat 2 comments

In my android apps I was getting annoying problems that whilst playing sound the volume buttons would control the media volume, but when no sound was playing they would control the ringtone volume. I found the following by trial and error, hopefully this post will help people with the same problem.

This is done by placing a call of setVolumeControlStream in the onCreate part of your activity which takes on of the following values

  • AudioManager.STREAM_MUSIC
  • AudioManager.STREAM_RING
  • AudioManager.STREAM_ALARM
  • AudioManager.STREAM_NOTIFICATION
  • AudioManager.STREAM_SYSTEM
  • AudioManager.STREAM_VOICECALL

Below shows the code required to set your applications default volume control to any of the above values:

Media Volume

this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

Ringtone Volume

this.setVolumeControlStream(AudioManager.STREAM_RING);

Alarm Volume

this.setVolumeControlStream(AudioManager.STREAM_ALARM);

Notification Volume

this.setVolumeControlStream(AudioManager.STREAM_NOTIFICATION);

System Volume

this.setVolumeControlStream(AudioManager.STREAM_SYSTEM);

Voicecall Volume

this.setVolumeControlStream(AudioManager.STREAM_VOICECALL);

I imagine this is also possible via and XML settings, if anyone knows of this I’d be very grateful to know how!

Categories: Android Tags: , ,

Android: Unreal Tournament SoundBoard

January 27th, 2010 mat 2 comments

Following the popularity of my counter-strike 1.6 soundboard and requests for the “HEADSHOT” noise for it, I have created an Unreal Tournament soundboard (from which the headshot sound originates).

Sounds:
Features all of the following sounds:

  • dominating
  • double kill
  • first blood
  • god like
  • headshot
  • holy shit
  • killing spree
  • ludicrous kill
  • mega kill
  • monster kill
  • multi kill
  • play
  • rampage
  • ultra kill
  • unstoppable
  • wicked sick

Screenshots
The following are screenshots from the application:

unreal tournament soundboard

unreal tournament soundboard

Unreal tournament soundboard

Unreal Tournament Soundboard 2

Download
Unreal Tournament SoundBoard can be downloaded from the market on your android phone either by searching or following the android link below. Alternativly you can download the apk file from this website using the download link

Android: UTsoundboard
Download: UTsoundboard download

If you enjoyed this please leave feedback for me either here or on the market. Comments, suggestions and constructive criticism is also welcome.

Categories: Android Tags:

Android: Saving a sound file to SD from resource and setting as ringtone

January 26th, 2010 mat 9 comments

Quite a few people have been asking how to save a file to the SD card in order to register it as a ringtone. The following example creates a function that will save a resource to the SD card (ie: from R.raw.soundfile to /sdcard/media/audio/ringtones/soundfile.wav) and register it as a ringtone.

I have split this example into two parts, the first part goes through the code a section at a time with a brief explanation of what it does, the second half is just the code that you can copy and paste and then edit to your hearts content.

Parts

We first setup our function to return a boolean depicting if we have failed or if we are successful. We accept in an integer which corresponds to the raw sound file.

public boolean saveas(int ressound){

}

So this function would be called in the following fashion:

saveas(R.raw.soundfile);

or utilising its boolean return:

if (saveas(R.raw.soundfile)){
// Code if successful
}
else
{
// Code if unsuccessful
}

The following chunk of code creates an inputstream from the raw sound resource and loads it into a buffer. We add in the mandatory try/catch clause around these operations and return false if an exception is raised (to indicate failure to the rest of our program and to prevent trying to continue act upon this sound).

 byte[] buffer=null;
 InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
 int size=0;

 try {
  size = fIn.available();
  buffer = new byte[size];
  fIn.read(buffer);
  fIn.close();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }

The following saves the buffer to a file on the SD card. It first ensures the folder exists and if not it is created. Then as before the writing operations are surrounded with try/catches

 String path="/sdcard/media/audio/ringtones/";
 String filename="examplefile"+".wav";

 boolean exists = (new File(path)).exists();
 if (!exists){new File(path).mkdirs();}

 FileOutputStream save;
 try {
  save = new FileOutputStream(path+filename);
  save.write(buffer);
  save.flush();
  save.close();
 } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  return false;
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }

The following code sends an intent to tell the Media Scanner that we have added a new file, and sets up its properties in the media database:

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));

 File k = new File(path, filename);

 ContentValues values = new ContentValues();
 values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
 values.put(MediaStore.MediaColumns.TITLE, "exampletitle");
 values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
 values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
 values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
 values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
 values.put(MediaStore.Audio.Media.IS_ALARM, true);
 values.put(MediaStore.Audio.Media.IS_MUSIC, false);

 //Insert it into the database
 this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);

Final code
Putting all this code together gives us our final functions:

public boolean saveas(int ressound){
 byte[] buffer=null;
 InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
 int size=0;

 try {
  size = fIn.available();
  buffer = new byte[size];
  fIn.read(buffer);
  fIn.close();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }

 String path="/sdcard/media/audio/ringtones/";
 String filename="examplefile"+".wav";

 boolean exists = (new File(path)).exists();
 if (!exists){new File(path).mkdirs();}

 FileOutputStream save;
 try {
  save = new FileOutputStream(path+filename);
  save.write(buffer);
  save.flush();
  save.close();
 } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  return false;
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }    

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));

 File k = new File(path, filename);

 ContentValues values = new ContentValues();
 values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
 values.put(MediaStore.MediaColumns.TITLE, "exampletitle");
 values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav");
 values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
 values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
 values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
 values.put(MediaStore.Audio.Media.IS_ALARM, true);
 values.put(MediaStore.Audio.Media.IS_MUSIC, false);

 //Insert it into the database
 this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);

 return true;
}

Comments, suggestions etc. are always welcome. Hope this has been helpful.

Categories: Android Tags: , , ,

Android: Opening a webpage in your app using Intents

January 25th, 2010 mat 2 comments

Opening up a website from an application in android is very simple thanks to “Intents”. An Intent is a request to android use an application to preform a task. The code below shows a very simple example of launching a browser to go to the wordcube website.

Context context = getApplicationContext();
String url = "http://www.stealthcopter.com/wordcube";
Intent i = new Intent(Intent.ACTION_VIEW);
Uri u = Uri.parse(url);
i.setData(u);
try {
  // Start the activity
  startActivity(i);
} catch (ActivityNotFoundException e) {
  // Raise on activity not found
  Toast toast = Toast.makeText(context, "Browser not found.", Toast.LENGTH_SHORT);
}

As pointed out in the comments, the context can be replaced by the activity itself, such as TestApp.this. eg:

Toast toast = Toast.makeText(TestApp.this, "Browser not found.", Toast.LENGTH_SHORT);

We have surrounded the activity with a try/catch which will be raised if android cannot find an application that will accept this intent, in this case a web-browser. It is highly unlikely that an android phone will not have a web-browser installed but it is a good practise to get into.

Categories: Android Tags: , ,

Android: WordCube – Daily puzzle game

January 23rd, 2010 mat No comments

Due to the success (and small amount of addiction) of my browser-based wordcube game (see here), I decided to make a WordCube application for android.

Features

  • Anagram / Wordsearch based puzzle
  • Small file size (~100kb) and footprint
  • Updated daily
  • Share score with twitter integration (compete with friends)
  • Saves your last attempts so you can continue at later time
  • This also means you can continue your last game offline
  • Several achievements can be unlocked (more to come, also looking for suggestions for achievements)
wordcube screenshot

screenshot of wordcube

Gameplay
Find as many words as possible using letters from the grid. The words must be 4 letters or more, contain the central letter and each letter may not be used more than once. There is at least one word that uses all of the letters in the cube.

The main interface is by tapping the letters in order to construct a word, but keyboards (and on screen keyboards) are also supported.

wordcube screenshot 2

Another wordcube screenshot

Twitter Integration
Once you have attained all the words that you can, you can post your score to twitter and then compare with your friends to see how they did in comparison. In order to use this feature you need to have a twitter client installed, I would recommend twidroid.

wordcube twitter integration

Twitter integration in wordcube

Download
WordCube can be downloaded from the market on your android phone either by searching for wordcube or following one the two android links below. To download the WordCube app from this website, follow the Web link.

Android: WordCube Free
Android: WordCube Pro (only £1)
Web: WordCube Free

The pro version is available for £1, with the money going to support the developer and the development and maintenance of this application. The pro version features all of the latest features and in the near future will support personal statistics to keep track of performance.

If you enjoyed this please leave feedback for me either here or on the market. Comments, suggestions and constructive criticism is also welcome.

Categories: Android Tags: , ,

Android: Eclipse and problems with dynamic tables (adding rows)

January 20th, 2010 mat 1 comment

When using TableLayout with LayoutParams Eclipse will automatically (and wrongly) add the following import:

import android.view.ViewGroup.LayoutParams;

However if you try to use this you will notice that nothing changes. You need to replace the import with the ollowingL

import android.widget.TableRow.LayoutParams;

Now if you rerun your code, you will see that your tables are updating. See below for an example of the code to generate a table

int sizey=10;
int sizex=10;
int btnwidth=24;
TableLayout tl = (TableLayout)findViewById(R.id.MyTableLayout); 

for (int y=0;y<sizey;y++){

// Rows
TableRow tr = new TableRow(this);
tr.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));

//Cells
for (int x=0;x<sizex;x++){
// Create new cell
	// new button
	Button b = new Button(this);
	b.setText(x+""+y);
	b.setLayoutParams(new LayoutParams(
		LayoutParams.FILL_PARENT,
		LayoutParams.WRAP_CONTENT));
	b.setHeight(btnwidth);
	b.setBackgroundResource(R.drawable.btn_blue);
	b.setOnClickListener(new PegOnClickListener(y,x));
	// add button to row
	tr.addView(b);
	}
// add row to layout
tl.addView(tr,new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
}
Categories: Android Tags: , ,

Android: Blurring and dimming background windows from dialogs

January 17th, 2010 mat 3 comments

The android SDK has lots of nice goodies built in to make your applications look sexier. One such feature is the blurring of windows. This effect looks particularly nice if a background window is blurred while a dialog box is shown above which can really make it stand out. Below shows the application such an example; on the left is the default about box (for WordCube Pro) and on the right is with added blur and no dimming.

android blur dim, before, after

android bluring and dimming effect before and after

I am using the AlterDialog.Builder to create my dialog, however this method will work with all kinds of dialog providing you can access it via getWindow.

   dialog = new AlertDialog.Builder(WordCube.this)
   .setTitle(WordCube.this.getResources().getString(R.string.app_name))
   .setMessage(s)
   .setIcon(R.drawable.logo)
   .setPositiveButton(R.string.btn_close, null)
   .show();

Below shows the code needed to add blur and remove dimming of the background (as I think the blur looks nicer when the background is well lit).

WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
lp.dimAmount=0.0f;
dialog.getWindow().setAttributes(lp);
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

The blur is simply created using the last line (line 4) which sets a flag for the dialog telling android that we want windows below this one to be blurred. To achieve the dimming, we need to retrieve the layout parameters for the dialog window, set the dim amount to zero, update these parameters with setAttributes (lines 1-3).

Any comments, questions, or improvements please let me know.

Categories: Android Tags: , , ,
// unused langs // // // //