Wednesday, July 8, 2009

How to protect part of a public method from being executed by others

I recently had to face this problem while I was modifying the android framework to add a security feature and I didn't want 3rd party apps to be able to mess with it.

To solve this problem I used enforceCallingOrSelfPermission.

Anything you do in your code until you call that method will be runnable by anyone who can access your method but passed this point it will through a SecurityException If neither you nor the calling process has been granted a particular permission.

Here's what it looks like:
void myMethod() {
// my code every one has access to...
myContext.enforceCallingOrSelfPermission(myPermission, myMessage);
// my super code that noone else can execute
}

Wednesday, June 17, 2009

How to have a few layout elements wrap around

Here is a problem people might encounter when dealing with layouts on android.

Say you want to place an image at the middle of a sentence. you may add a couple TextView and an ImageView but if the horizontal space gets too small the two TextViews are going to start wrapping around independently wich is going to look weird. You'd want the image to be part of your TextView and the entire sentence to wrap around nicely.

To do so:
* replace the three objects by one Spannable TextView
* use a SpannableStringBuilder to append all your strings (don't forget to add an extra character (a space for example) that will be replaced by your image)
* and finally use setSpan(ImageSpan, begin, end, flag) on that builder where ImageSpan is an ImageSpan containing the drawable of your picture, begin is the index of the character you've inserted

So instead of having something that looks like this:
I really really really really like Posted by Picasa Picasa because it's a very very very very nice free image editing software

You get something that looks more like that:
I really really really really like Posted by Picasa Picasa because it's a very very very very nice free image editing software

And here's what the code would look like:

add android:bufferType="spannable" to your TextView

SpannableStringBuilder builder
= new SpannableStringBuilder();
builder.append(mContext.getText(R.string.part1));
int lengthOfPart1 = builder.length();
builder.append(" ");
builder.append(mContext.getText(R.string.part2));
Drawable d = mContext.getResources().getDrawable(R.drawable.picasaIcon);
d
.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); // <---- Very important otherwise your image won't appear
ImageSpan myImage = new ImageSpan(d
);
builder.setSpan(myImage, lengthOfPart1, lengthOfPart1 + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
myTextView.setText(builder);

Tuesday, June 16, 2009

How to create a custom progress bar

First you need to create a progress bar layout file. Let's call it my_custom_pb.xml

<
layer-list xmlns:android="http://schemas.android.com/apk/res/android">


<item android:id="@android:id/background" android:drawable="@drawable/mybg"/>


<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#80d3ff00"
android:centerColor="#80b6ff00"
android:centerY="0.75"
android:endColor="#a0cbff00"
android:angle="270"
/>

</shape>
</clip>
</item>

<item android:id="@android:id/progress">
<clip android:drawable="@drawable/myprogress"/>
</item>
</layer-list>

Notice you can either use a simple 9 patch drawable or make your own custom shape!
Then you would add that custom progress bar to the layout you want that bar to appear:

<ProgressBar
android:id="@+id/mypb"
android:layout_width="120px"
android:layout_height="10px"
android:progressDrawable="@drawable/my_custom_pb"
android:max="5"
android:progress="1" />

And finally you would access it from your code like you would with any regular progress bar:

myProgress = (ProgressBar)findViewById(R.id.mypb);
myProgress.setProgress((int)value);
--
Special Thx to Mikael for this one.

Using resources

When using resources the name used behind the @ sign is not the name of the resource file you will find that value in but the type of resource you are refering to. here xxxx is the type and yyyy is the name of the variable you're using. So your layout file would have something like this:

android:background="@xxxx/yyyy"

and your resource file (say mySuperRes.xml) would look something like that:

<xxxx name="yyyy">zzzz</xxxx>

Adding and removing things to the API

  • If you want to add a system setting or anything to the API you need to run:

make update-api

  • If you remove a system setting or anything from the API and end up with this error:

******************************
You have tried to change the API from what has been previously released in
an SDK. Please fix the errors listed above.
******************************
you need to run:

make update-api

if that doesn't do it edit "build/core/api/current.xml" and "build/core/api/1.xml" and make sure your setting is no longer there.

How to pop a toast (sort of alert messages)

An easy one to start (for all you beginners out there):

Toast.makeText([the current context, for example: this], "Hello World", Toast.LENGTH_LONG).show();

Welcome

Hi to all Android developers that are looking for good tips.
Here is the place where I'll be writing all the little things that helped me in my Android development career.