Django: Display boolean field as True/False radio buttons

This sounds like such a trivial thing to do but it wasn't the most logical.

imageAlright, you'll need a tuple that contains the True/False value and labels and then a ChoiceField which uses it.

class CustomForm(forms.Form):
BOOLEAN_CHOICES = (('1', 'True label'), ('0', 'False label'))
# Filtering fields
is_true = forms.ChoiceField(choices = BOOLEAN_CHOICES, widget = forms.RadioSelect)

Oh what? We're done!

tumblr_lhrs2y4gG21qc45d0

Source

Django: Dynamic checkbox/select options in form

Usually when you create a form in Django, you have to know what items you want to allow as the initial values, otherwise it'll give you an invalid_choice error:

Select a valid choice. 'X' is not one of the available choices.

Normally it's fine, it's just some dope changing values on their browser and messing with your form by sending dodgy data.

But things get a little more complicated when you NEED dynamic choices in the form. For example, I want a form that will allow the user to list a bunch of cars with a given set of features. The "manufacturers" list we can generate using ModelChoiceField, but when you select one, it uses Ajax to dynamically change the "features" options.

note: This example is more verbose than it needs to be. That's just to help you understand what's going on. You can trim off the excess fat once you've got a hang of things.

Firstly, subclass the django.forms.MultipleChoiceField class.

class DynamicMultipleChoiceField(forms.MultipleChoiceField):
# The only thing we need to override here is the validate function. 
    def validate(self, value):
if self.required and not value:
raise ValidationError(self.error_messages['required'])

# Twig: This is part of the original code that we don't want.
# Validate that each value in the value list is in self.choices.
#for val in value:
# if not self.valid_value(val):
# raise ValidationError(self.error_messages['invalid_choice'] % {'value': val})

Now in your form, change the existing field of choice to use the new DynamicMultipleChoiceField:

class CarForm(forms.Form):
manufacturer = forms.ModelChoiceField(queryset = Car.objects.order_by('name'))
features = DynamicMultipleChoiceField(widget = forms.CheckboxSelectMultiple(), choices = [])

def filter_features(self, data):
items = Features.objects.order_by('name')
query = data.get('filter_manufacturer_id', 0)

if query:
manufacturer = Manufacturer.objects.get(pk = query)
items = items.filter(manufacturer = manufacturer)

self.fields['features'].choices = [ (item.pk, item.name) for item in items ]

What we've done here is set the field to be our DynamicMultipleChoiceField, but use the CheckboxSelectMultiple widget to render it.

When the manufacturer list changes, use Ajax to post the selected manufacturer information (your choice of either ID or name). Assuming you've set it up correctly, you can replace the whole choice field with the output from this view:

def ajax_features_field(request):
form = CarForm()
form.filter_features(request.POST)

return HttpResponse("%s" % form['features'])

All the view does is return the rendered HTML for just the features field. If you've customised the form, add a little wrapper  class/ID so you can use jQuery to easily replace the whole field.

tumblr_lfi3fzbYg61qahhxwo1_250
Feature: I want a car that can park like Japan!

Source

Python: How to write a CSV file

CSV is one of the oldest and simplest format for spreadsheets.

If you've ever found yourself having to dump out some data in this format, Python makes it hella easy to do so.

headings = ['Category', 'Systemtype', 'SystemModel', 'ModelID', 'Type', 'Manufacturer', 'ProductName', 'OrigProductName', 'Processor', 'ProcessorSpeed', 'Monitor', 'Memory', 'OperatingSystem', 'HardDrive' ]

# Open up the CSV writer
file = open("something.csv", 'wb')
writer = csv.writer(file, delimiter = ',', quotechar = '"')
writer.writerow(headings)

row = []
for field in headings:
row.append(p.get(field, '').strip().encode("utf-8"))
writer.writerow(row)

file.close()

As you can see, the csv module makes life really easy!

One thing to keep in mind is the encode("utf-8") bit is important, as the CSV module doesn't support unicode by default.

Sources

Android: Validate a URL string

Sometimes all we really need is to check if a URL is valid. You know, the standard "http(s)://domain.com/something/" pattern.

It took a while to find, but the API level 1 had it all along!

Just use URLUtil.isValidUrl() to test it.

// Validate URL
if (!URLUtil.isValidUrl(url)) {
Toast.makeText(this, "Invalid URL specified", Toast.LENGTH_SHORT).show();
return;
}

That's all folks!

 slidedog
Back to having fun!

Sources

Django: Fix "OperationalError: database is locked" error

If you're using the shell to do some testing, this error could cause you some grief and set you back by forcing you to start the terminal.

Thankfully, the solution is short.

Just paste in this snippet and it'll be rolled back to a usable state.

from django.db import transaction
transaction.rollback()

Sources

jQuery: Detect enter keypress

A neat little snippet which detects when a user has pressed "Enter" on the keyboard.

$('#id_query').keypress(function(e) {
var key = (e.keyCode || e.which);

if (key == 13) {
e.preventDefault();
alert("hi!");
}
});

Sources

Django: How to fix the annoying UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)

A somewhat tricky error to debug.

Take for example this:

>>> u"%s" % Product.objects.get(pk = 7431).manufacturer 
u'DéLonghi'

Now look at it again.

>>> "%s" % Product.objects.get(pk = 7431).manufacturer
'D\xc3\xa9Longhi'

Did you spot the difference? There's a "u" in front of the string. That "u" tells Python you want it to be a unicode string rather than an ASCII string.

>>> product = Product.objects.get(pk = 7431)

>>> "%s %s" % (product.manufacturer, product.name)

Will throw this exception

Traceback (most recent call last):
  File "<console>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)

Using the unicode string formatter:

>>> product = Product.objects.get(pk = 7431)

>>> u"%s %s" % (product.manufacturer, product.name)
u'D\xe9Longhi PLS130ARAUP'

Phew, that took a while to figure out. Now back to work!

image

Python: Check if an IP matches or in a valid range

While implementing a certain feature, we wanted to restrict it's functionality to a range of IP's only available in the office.

To do that, you first need to download netaddr from github.

import netaddr

def cache_purge_allowed(request):
client_ip = request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR', None))

if client_ip is None:
return False

ip = netaddr.IPAddress(client_ip)
return (ip in netaddr.IPNetwork('203.34.46.0/23')) or (ip in netaddr.IPNetwork('192.168.0.0/16')) or (ip in netaddr.IPNetwork('119.225.10.1'))

The example searches through 2 IP ranges and then compares to an exact IP match.

Sources

Django: Model distinct() and order_by() not working nicely together

An interesting (and somewhat tedious) problem came up. We wanted to gather the most recently active blog authors sorted by post date.

Basically, it'd just be a distinct on the authors while sorting by latest post publication date.

In the words made famous by Jeremy Clarkson on Top Gear, "How hard can it be?". To be honest, quite hard.

Things were duplicated everywhere! After a few hours of tinkering, we found a solution.

from django.db.models.aggregates import Max

Author.objects.all_active_in_site().annotate(latest_published = Max('posts__published')).order_by('-latest_published')

It may look ridiculously simple, but it works!

Annotate sets "latest_published" to the date of the newest blog post (found using Max), removing duplications in the matching table.

Since it thinks there is only one blog entry per author, we don't get duplicates when joining.

Source

Python: Fetching HTTPS urls which require username/password authentication

It wasn't the easiest solution to find on the net, but a fairly simple one to implement.

Some solutions even suggest recompiling Python with OpenSSL installed. Sorry, too much trouble, not an option!

from urllib2 import URLError, HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, install_opener, build_opener

# Set up a HTTPS request with username/password authentication
try:
# create a password manager
password_mgr = HTTPPasswordMgrWithDefaultRealm()

# Add the username and password.
password_mgr.add_password(None, feed_url, "your_username", "your_password")
opener = build_opener(HTTPBasicAuthHandler(password_mgr))
file = opener.open(feed_url)

# After you get the "file", you pretty much work with it the same way as you normally would.
xml = etree.parse(file)

except URLError, e:
print 'URLError: "%s"' % e
raise

Brush your hands off boys, we're done here.

Now to solve more pressing issues...

ExtRS
How to get that damn toilet tissue?

Source

Python: Calling CLI (command line) functions from code

This was a tricky one for me. I was trying to use wget to download a file but it wouldn't work properly!

subprocess.call("wget --tries=3 --retry-connrefused http://dl.dropbox.com/u/446679/dog-bites-cat.jpg")

Once I ran it...

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python2.6/subprocess.py", line 470, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib/python2.6/subprocess.py", line 623, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1141, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

What the hell? Everything is right!

Turns out I was missing a certain keyword in the call. Some functions require you to add in "shell = True".

subprocess.call("wget --tries=3 --retry-connrefused http://dl.dropbox.com/u/446679/dog-bites-cat.jpg", shell = True)

Source

Python: Download image file from URL and retrieve common properties

With the following snippets, you can get yourself:

  • Image width/height
  • Image mime type
  • File size

So, the code snippet!

from PIL import Image
import urllib2
import cStringIO
import os
from stat import ST_SIZE


file = cStringIO.StringIO(urllib2.urlopen(image_url).read())
filename = "/tmp/file_%s.jpg" % datetime.datetime.now().strftime("%s")

image_info = Image.open(file)
image_info.save(filename)
file.close()

file_info = os.stat(filename)

filemime = "image/%s" % image_info.format.lower() # JPEG, PNG, GIF
width, height = image_info.size
filesize = file_info[ST_SIZE]

From Doug Hellmann's blog:

The cStringIO version is written in C for speed, while StringIO is written in Python for portability.

Once you're done, remember to delete the temporary file.

os.remove(filename)

Sources

jQuery: Slide left and right like slideUp/slideDown but horizontally

So easy that I wish I found this information sooner!

To show:

$('#selector').animate({ width: 'show' });

To hide:

$('#selector').animate({ width: 'hide' });

Alternatively, you can also give a fixed width when showing it.

Other than that, OMG you're done!

OMG

Source

Django: Dynamic forms with dynamic fields

Ok, dynamic fields. Now we're digging into the dark depths of Django. Not something you can find in the documentation, well me anyway.

There are a few posts online about it but some are fairly old, before the Django "newforms" were introduced. All that means is if you tried that code it won't work.

This example shows us how to:

  • Pass an argument to the form upon creation (user variable)
  • Dynamically create fields upon creation
  • Modify the choices for an existing field upon creation

These should cover the use cases of most dynamic forms.

class ExampleDynamicForm(forms.Form):
normal_field = forms.CharField()
choice_field = forms.CharField(widget = forms.Select(choices = [ ('a', 'A'), ('b', 'B'), ('c', 'C') ]))

def __init__(self, user, *args, **kwargs):
# This should be done before any references to self.fields
super(ExampleDynamicForm, self).__init__(*args, **kwargs)

self.user = user
self.id_list = []

# Some generic loop condition to create the fields
for blah in Blah.objects.for_user(user = self.user):
self.id_list.append(blah.id)

# Create and add the field to the form
field = forms.ChoiceField(label = blah.title, widget = forms.widgets.RadioSelect(), choices = [('accept', 'Accept'), ('decline', 'Decline')])
self.fields["blah_%s" % blah.id] = field

# Change the field options
self.fields['choice_field'].widget.choices = [ ('d', 'D'), ('e', 'E'), ('f', 'F') ]

To use the form:

form = ExampleDynamicForm(request.user)

nickshock

It may look scary but it's not that bad.

Follow the formula and you'll be fine.

Note: Remember, the super().__init__() call should be made early on before any references to self.fields.

Sources

Django: Optgroup option groups for Select field widgets

To get your select choices to be grouped, you'll have to do a little trickery.

image

The resultant output in HTML is:

<select id="id_choice" name="choice">
<optgroup label="Audio">
<option value="vinyl">Vinyl</option>
<option value="cd">CD</option>
</optgroup>
<optgroup label="Video">
<option value="vhs">VHS Tape</option>
<option value="dvd">DVD</option>
</optgroup>
<option value="unknown">Unknown</option>
</select>

This example shows you how to provide a list of hardcoded options and it's straight out of the Django docs.

from django import forms

MEDIA_CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
)

class ExampleForm(forms.Form):
choice = forms.CharField(widget = forms.Select(choices = MEDIA_CHOICES))

That's it. Now you have the choices grouped in your form.

Now you can feel like a pro until you need dynamic choices!

Tablecloth_trick

Sources

Diablo 2 + Lord of Destruction: Play without CD

As of patch v1.12, Blizzard allowed the game to be played without CD since they were offering the digital copy of it from their online store.

--------------------------------------------------------------------------
- Patch 1.12
--------------------------------------------------------------------------

     Downloadable Installer Support

- If all required Diablo 2 '.MPQ' files are installed on the
  hard drive, the game will no longer require the CD to play.

   For users that originally performed a 'Full Installation'
   and wish to run without the CD, all '.MPQ' files should
   be copied from the Diablo 2 CDs to the Diablo 2 directory. 
   Most users will only need to copy D2Music.mpq from the
   Diablo 2 Play CD and/or D2xMusic.mpq from the Lord of
   Destruction CD.  Mac users will need to copy these music
   files and rename them to 'Diablo II Music' and
   'Diablo II Expansion Music' respectively.

So, assuming you've done a "full" install of the Diablo 2 game and that you've installed the expansion pack, you'll also need to copy over D2xMusic.mpq from the expansion CD to your installation folder (by default it should be C:\Program Files\Diablo II).

Something they forgot to mention is that you'll also need D2XVIDEO.MPQ as well. Otherwise you'll get the annoying "Insert Expansion Disc" message when you try to start the game.

image

It should work straight away once you've got those 2 files in your game folder.

Android: Uploading files from the phone to a web server via HttpPost

Alright, I'm getting sleepy so this post is straight down to business.

The early Android core libraries didn't come with very much in terms of HTTP and net socket support. The majority of the time they just said "use Apache's library, they're better".

Android has caught up, but if you want to keep existing devices happy, you'll still need the Apache libraries.

  • Under HttpClient 4.1.2 (GA), download 4.1.2.zip.
  • Create a folder in your project called "lib".
  • Open up the zip archive and look for "httpcomponents-client-4.1.2-bin-2.zip\httpcomponents-client-4.1.2\lib\httpmime-4.1.2.jar"
  • Extract it into the new lib folder.

In Eclipse:

  • Refresh your project
  • Right click your project
  • Select "Properties"
  • Go to "Java Build Path > Libraries > Add Jars"
  • Select "httpmime-4.1.2.jar".

image

Now you're ready to CODE!

HttpClient httpClient;
HttpPost postRequest;
MultipartEntity reqEntity;
ResponseHandler responseHandler;
File file;
FileBody fileBody;

httpClient = new DefaultHttpClient();
postRequest = new HttpPost(targetUrl);
responseHandler = new BasicResponseHandler();

// Indicate that this information comes in parts (text and file)
reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

file = new File(filename);
fileBody = new FileBody(file, "images/jpeg");
reqEntity.addPart("fileupload", fileBody);

try {
// The rest of the mundane data
reqEntity.addPart("username", new StringBody("twig"));
reqEntity.addPart("password", new StringBody("haha_as_if!"));

// Prepare to ship it!
postRequest.setEntity(reqEntity);
httpClient.execute(postRequest, responseHandler);
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}

The file mimetypes you can get from my post Android: Get file mime type from filename.

2clfkn
Now you ride like a BOSS!

Source

Android: Allow user to edit/input text from an alert dialog

This little snippet is a simple one, but it makes the user experience a whole lot better.

Instead of implementing a new Activity/screen to enter in some text, just make it an AlertDialog() with an EditText view.

final EditText txtUrl = new EditText(this);

// Set the default text to a link of the Queen
txtUrl.setHint("http://www.librarising.com/astrology/celebs/images2/QR/queenelizabethii.jpg");

new AlertDialog.Builder(this)
.setTitle("Moustachify Link")
.setMessage("Paste in the link of an image to moustachify!")
.setView(txtUrl)
.setPositiveButton("Moustachify", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String url = txtUrl.getText().toString();
moustachify(null, url);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
})
.show();

This does all the magic. The example shows you how to:

  • Create the edit textfield and assign some properties
  • Build the dialog
  • Set the title/message for the dialog
  • Embed the text field
  • Do something after the user clicks OK or Cancel

Obviously you're gonna have to fill the positive button action with your own intentions.

Have fun!

Source

Android: Select and open an image from Android's image gallery

Well this certainly was harder than it should have been! The first three steps are pretty straight forward.

Set up an ID for the activity result.

private final int ACTIVITY_CHOOSE_PHOTO = 1;

Mission complete! On with the next phase. Now we need something to trigger the "chooser" activity.

Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("image/*");
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);

startActivityForResult(Intent.createChooser(chooseFile, "Choose a photo"), ACTIVITY_CHOOSE_PHOTO);

Simple enough. Of course, if we're expecting a result then we need to actually do something with it.

So in your Activity.onActivityResult() callback method:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode) {
case ACTIVITY_CHOOSE_PHOTO: {
if (resultCode == RESULT_OK) {
String filename = parseUriToFilename(data.getData());

if (filename != null) {
moustachify(filename, null);
}
}
break;
}
}
}

OK, the first three steps are done. It's just copy pasting code anyway...

Now the magic calculations come into play to get the filename. Otherwise you'll get references to the media manager and other funky stuff we don't really care about.

Note: This is the exact same code you'll see in the post Android: Add your application to the "Share" menu as they use information from the same activities.

public String parseUriToFilename(Uri uri) {
String selectedImagePath = null;
String filemanagerPath = uri.getPath();

String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);

if (cursor != null) {
// Here you will get a null pointer if cursor is null
// This can be if you used OI file manager for picking the media
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
selectedImagePath = cursor.getString(column_index);
}

if (selectedImagePath != null) {
return selectedImagePath;
}
else if (filemanagerPath != null) {
return filemanagerPath;
}
return null;
}

Now that you've solved this problem, I'm sure there's another waiting for you under the lid somewhere in the near future...

1vcZA

Source

Android: Detect when a WebView has finished loading

To know when a WebView has finished loading, you can set a WebViewClient() handler and override the onPageFinished() method.

ProgressDialog progressDialog = new ProgressDialog(ResultActivity.this);
progressDialog.setMessage("Loading ...");

progressDialog.setCancelable(false);
progressDialog.show();

WebView wv = new WebView(this);

wv.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressDialog.hide();
}
});

wv.loadUrl(some_url);

This example shows a "loading dialog" while the webview loads in the background. It'll go away once the page has fully loaded.

1246086511568

Just like when the Jedi warriors have finished defeating enemies, at the end of the battle they force push a fat dude off his chair.

Source

Android: Retrieve "version name" from AndroidManifest.xml

I was getting sick of updating the version number on multiple places in my app when releasing updates; "About" screen, "version" variable and then in the Android manifest.

Since the application manifest already had android:versionName, why not use it?

try {
MyActivity.GAME_VERSION = getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
}
catch (NameNotFoundException e) {
// I don't think this ever happens, but let me know if it does!
MyActivity.GAME_VERSION = "0.00";
}

So easy, should have looked it up earlier!

122500549513
Now I'm laughing at version changes!

Source

Android: Resize a Bitmap image while dealing with immutable Bitmaps and OutOfMemoryError exceptions

When I was first debugging my image watermark code, I found it strange it kept running out of memory. Why!?

You're doing it wrong!

Firstly, I was trying to edit an immutable (non-editable) Bitmap. You need to generate a mutable copy of the bitmap before you can start modifying it.

Secondly, my method was very heavy on memory usage. It involved loading the original immutable +4mega-pixel image into memory, then creating a new mutable Bitmap of equal size and colour depth, copying it over using a Canvas.

Keep in mind, the Android VM only allows 16M of memory per app. Each pixel in your image using ARGB_8888 can use up to 4 bytes of memory.

To help you get a perspective of things, a 32bit image with 724x724 has 524,176 pixels uses up 15.9M of memory. If you squish the sizes a bit, that's not very much on a mobile device, especially when you factor in that you need memory for other things in your app such as GUI elements and references to your Activity.

What does that mean? It means you can't load that 8mb photo on that SD card in full resolution no matter how hard you try. Your app has to make some compromises and trim it down a bit.

Not to mention my third step was to imprint a logo over the mutable new bitmap, which means loading yet another image into memory.

turtle-power
This is what the current situation felt like...

Looking for an answer

The internet and StackOverflow are littered with questions on this issue. Most responses tell you to either reduce the colour depth, partially process the bitmap or call Bitmap.recycle() on the source image before creating a new Bitmap.

Now that doesn't make much sense if I'm trying to COPY an image from Bitmap A to Bitmap B because I need both of them in order to do that.

Option A - Bump up the API level

BitmapFactory.Options has a new flag inMutable that allows loading of mutable bitmaps in Honeycomb (API level 11), but I try to maintain as much compatibility as possible.

If you choose to go this way, you will lose some of your market share. See the Android documentation for more information about which API level corresponds to the Android platform versions.

Since I don't actually have any Honeycomb compatible devices, this simply wasn't an option.

Option B - Load a smaller image

My preferred solution is to "pre-scale" the source bitmap so it isn't so damn big. That means loading it in a smaller immutable resolution so you have enough memory to hold both bitmaps at the same time.

The ideal size is 630px, since that's what Facebook uses for the photo album pictures and most people seem to be happy with it.

The downside is that scales works best in the power of 2's, so you can load an image that is 1/2 the size of the original, 1/4th the size, 1/8th the size, etc.

So the method here is:

  • Open image and fetch it's dimensions
  • Scale the image accordingly so it'll meet our "maximum pixels" criteria.
  • Load a pre-scaled image.
  • Create a new mutable bitmap with the same dimensions
  • Copy it via a Canvas
  • Recycle the source bitmap
private Bitmap loadPrescaledBitmap(String filename) throws IOException {
// Facebook image size
final int IMAGE_MAX_SIZE = 630;

File file = null;
FileInputStream fis;

BitmapFactory.Options opts;
int resizeScale;
Bitmap bmp;

file = new File(filename);

// This bit determines only the width/height of the bitmap without loading the contents
opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
fis = new FileInputStream(file);
BitmapFactory.decodeStream(fis, null, opts);
fis.close();

// Find the correct scale value. It should be a power of 2
resizeScale = 1;

if (opts.outHeight > IMAGE_MAX_SIZE || opts.outWidth > IMAGE_MAX_SIZE) {
resizeScale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(opts.outHeight, opts.outWidth)) / Math.log(0.5)));
}

// Load pre-scaled bitmap
opts = new BitmapFactory.Options();
opts.inSampleSize = resizeScale;
fis = new FileInputStream(file);
bmp = BitmapFactory.decodeStream(fis, null, opts);

fis.close();

return bmp;
}

The rest of the code can be found here.

Option C - Stash the bitmap away in a file

Well, a very interesting and creative method from Sudar Nimalan that will allow you to copy the full resolution image into a mutable form. It is however much slower.

His method involves:

  • Loading the original bitmap
  • Stashing the bitmap to a MappedByteBuffer
  • Recycling the original bitmap
  • Creating a new mutable bitmap
  • Copying the bitmap from the MappedByteBuffer

It's not as hard as it sounds and the code sample is quite short. Worth a look at if you're keen on keeping the image resolution intact.

Sources

Android: Download a file with progress indication

The following example shows you how to:

  • download a file
  • display the progress in a progress dialog
  • use AsyncTask
  • create a temporary file

tumblr_lnmev5uOLt1qly6u1o1_400
Like a BOSS

I've used this code in my app Moustachify Everything. Initially, the app didn't display the progress bar and it was annoying because you never know if it was actually doing anything.

it's a bit lengthy, but I assure you it's worth it for the user once you see it in action.

/**
* Downloads file from URL and does something with it.
*/
private void downloadFile(String url) {
final ProgressDialog progressDialog = new ProgressDialog(this);

new AsyncTask() {
private Exception m_error = null;

@Override
protected void onPreExecute() {
progressDialog.setMessage("Downloading ...");
progressDialog.setCancelable(false);
progressDialog.setMax(100);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

progressDialog.show();
}

@Override
protected File doInBackground(String... params) {
URL url;
HttpURLConnection urlConnection;
InputStream inputStream;
int totalSize;
int downloadedSize;
byte[] buffer;
int bufferLength;

File file = null;
FileOutputStream fos = null;

try {
url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();

urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();

file = File.createTempFile("Mustachify", "download");
fos = new FileOutputStream(file);
inputStream = urlConnection.getInputStream();

totalSize = urlConnection.getContentLength();
downloadedSize = 0;

buffer = new byte[1024];
bufferLength = 0;

// Read through the input buffer and write the contents to the file
while ((bufferLength = inputStream.read(buffer)) > 0) {
fos.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
publishProgress(downloadedSize, totalSize);
}

fos.close();
inputStream.close();

return file;
}
catch (MalformedURLException e) {
e.printStackTrace();
m_error = e;
}
catch (IOException e) {
e.printStackTrace();
m_error = e;
}

return null;
}

protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress((int) ((values[0] / (float) values[1]) * 100));
};

@Override
protected void onPostExecute(File file) {
// If there was an error, do something informative with it.
if (m_error != null) {
m_error.printStackTrace();
return;
}

progressDialog.hide();

// You probably want to do something else with this
file.delete();
}
}.execute(url);
}

Source

Android: Scale a watermark Bitmap over another Bitmap using the Matrix

What I set out to do was to overlay a logo over a photo and it was surprisingly easy with the use of the Matrix class.

image 
No no, not him!

I've littered the code with comments, but if you need any more information leave a comment.

/**
* Adds a watermark on the given image.
*/
public static Bitmap addWatermark(Resources res, Bitmap source) {
int w, h;
Canvas c;
Paint paint;
Bitmap bmp, watermark;

Matrix matrix;
float scale;
RectF r;

w = source.getWidth();
h = source.getHeight();

// Create the new bitmap
bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);

// Copy the original bitmap into the new one
c = new Canvas(bmp);
c.drawBitmap(source, 0, 0, paint);

// Load the watermark
watermark = BitmapFactory.decodeResource(res, R.drawable.android_mo);
// Scale the watermark to be approximately 10% of the source image height
scale = (float) (((float) h * 0.10) / (float) watermark.getHeight());

// Create the matrix
matrix = new Matrix();
matrix.postScale(scale, scale);
// Determine the post-scaled size of the watermark
r = new RectF(0, 0, watermark.getWidth(), watermark.getHeight());
matrix.mapRect(r);
// Move the watermark to the bottom right corner
matrix.postTranslate(w - r.width(), h - r.height());

// Draw the watermark
c.drawBitmap(watermark, matrix, paint);
// Free up the bitmap memory
watermark.recycle();

return bmp;
}

Sources

Android: Share an image to other apps

The last post was about receiving shared images.

To send off images to another app, just use:

Intent intent;
File file;

file = new File(absolute_filename);
intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));

startActivity(Intent.createChooser(intent, "Share photo"));

If you need to be particular about the mime type, see get file mime type from filename.

Sources

Android: Add your application to the "Share" menu

Photo gallery > Share > Your App.

share_thumb3

That'd be nice aye? Luckily, it's not that hard coz I've got sharing images or files using Intents working on my Mustachify Everything app quite nicely.

A couple of tweaks required though. First, indicate that your app is willing to deal with image files coming from the "SEND" action.

Using the Eclipse Android SDK, the AndroidManfest.xml config should look a little something like this:

image

  • Add an intent filter
  • Add an action with the value of "android.intent.action.SEND"
  • Add data with the value of "image/*" for mime type
  • Add a category with the value of "android.intent.category.DEFAULT"

In XML, it looks like this:

<intent-filter>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/*" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

That's the initial setup done.

Now to detect when your Activity was started by a sharing intent.

Sometime during Activity.onCreate(), we need to add some code to handle the incoming data:

Intent intent = getIntent();
Bundle extras = intent.getExtras();
String action = intent.getAction();

// if this is from the share menu
if (Intent.ACTION_SEND.equals(action)) { if (extras.containsKey(Intent.EXTRA_STREAM)) {
// Get resource path
Uri uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);
String filename = parseUriToFilename(uri);

if (filename != null) {
moustachify(filename, null);
}
}
}

This is the main gist of the logic required to get sharing working.

Now the magic contained in parseUriToFilename() converts the image path information into a usable file path and name. That's the hard part.

The code below is a cleaned up version of mad's solution.

public String parseUriToFilename(Uri uri) {
String selectedImagePath = null;
String filemanagerPath = uri.getPath();

String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);

if (cursor != null) {
// Here you will get a null pointer if cursor is null
// This can be if you used OI file manager for picking the media
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
selectedImagePath = cursor.getString(column_index);
}

if (selectedImagePath != null) {
return selectedImagePath;
}
else if (filemanagerPath != null) {
return filemanagerPath;
}
return null;
}

Now that you've got the absolute filename for the file shared, you can do whatever the heck you want with it.

Wrestler_kicks_girl 
Except this...

Sources

Android: Scale whole image to fit ImageView and keep aspect ratio

It took me a while to figure out, but it's not ScaleType.FIT_XY that does the trick but FIT_CENTER.

FIT_XY will stretch both width and height to fit the ImageView.

Remember to use ImageView.setImageDrawable() or setImageBitmap() rather than setBackgroundDrawable().

Source: Android: Scale a Drawable or background image?

Android: Loading jpg/png images from URL into a Bitmap or ImageView

I was being driven insane this weird bug. The idea was simple enough.

  1. Open a stream to a HTTP URL.
  2. Use BitmapFactory to decode the stream.
  3. ...
  4. Profit.

Worked pretty well in the emulator! But for some reason on the actual test devices, it would fail every single time. Mind boggling!

After a few tests, I noticed something in the error logs.

decoder->decode returned false

The reason why the image fails to decode is because InputStream doesn't actually implement the skip() method.

This post pointed me in the right direction. Still unsure of how to implement it properly, it lead to Deep Shah's post. He had a perfectly solid implementation of FlushedInputStream that was well documented.

Below is a slightly cleaned up version with less documentation. If you need more information about how it works, see his post.

/**
* The class that will provide the correct implementation of the skip method
* this class extends the FilterInputStream
*
* @author Deep Shah
*
* @see http://www.gitshah.com/2011/05/fixing-skia-decoder-decode-returned.html
* @see http://code.google.com/p/android/issues/detail?id=6066
*/
package twig.nguyen.mustachify;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(final InputStream inputStream) {
super(inputStream);
}

/**
* Overriding the skip method to actually skip n bytes.
* This implementation makes sure that we actually skip
* the n bytes no matter what.
*/
@Override
public long skip(final long n) throws IOException {
long totalBytesSkipped = 0L;

while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);

if (bytesSkipped == 0L) {
int bytesRead = read();

if (bytesRead < 0) { // we reached EOF
break;
}

bytesSkipped = 1;
}

totalBytesSkipped += bytesSkipped;
}

return totalBytesSkipped;
}
}

Believe it or not, that's the hard part done. All we gotta do now is use it.

private Bitmap loadBitmap(String url) throws MalformedURLException, IOException {
return BitmapFactory.decodeStream(new FlushedInputStream((InputStream) new URL(url).getContent()));
}

Whalla! With that Bitmap you can do whatever the heck you want with it.

2fingers
Back to other pressing matters...

Source

Android: Copy paste text from PC to emulator

Working with the Android emulator isn't as nice as working with a VMware virtual machine. You can't simply copy text from your notepad and paste it into the Android emulator.

A nice way of getting around it is using the SMS functionality accessible via telnet.

Assuming your emulator is running on port 5554, open up a command prompt window:

telnet localhost 5554

sms send +12345 your message begins here

For the phone number, you can just enter anything in. An error will show up telling you if anything is wrong.

Source

Windows 8 Developers Preview: Disable the Metro Interface

Sure it's designed for tablets and all, but I have a feeling Win8 might fall to the curse of the sucky "odd" release (Windows 3.1, Win98, XP and 7 were great! Win95, ME and Vista were terribad)

With this whole shift to ribbons and metro, I think I'll stick to Windows 7 (unless there was a way to disable all those bells and whistles).

You can grab a copy of it off Microsoft's official site.

Anyway, enough rambling. To disable the metro task "home" screen, either press "Win+R" to open up the Run dialog or open a command prompt.

Paste in:

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer /f /v RPEnabled /t REG_DWORD /d 0

Whalla!

Restart Windows 8 and you'll have rid yourself of that horrible tablet UI.

Source: Disable Metro UI And Get Windows 7 Styled Start Menu Back in Windows 8

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog