Categories
discuss

Decoding bitmaps in Android with the right size

I decode bitmaps from the SD card using BitmapFactory.decodeFile. Sometimes the bitmaps are bigger than what the application needs or that the heap allows, so I use BitmapFactory.Options.inSampleSize to request a subsampled (smaller) bitmap.

The problem is that the platform does not enforce the exact value of inSampleSize, and I sometimes end up with a bitmap either too small, or still too big for the available memory.

From http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize:

Note: the decoder will try to fulfill this request, but the resulting bitmap may have different dimensions that precisely what has been requested. Also, powers of 2 are often faster/easier for the decoder to honor.

How should I decode bitmaps from the SD card to get a bitmap of the exact size I need while consuming as little memory as possible to decode it?

Edit:

Current source code:

BitmapFactory.Options bounds = new BitmapFactory.Options();
this.bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, bounds);
if (bounds.outWidth == -1) { // TODO: Error }
int width = bounds.outWidth;
int height = bounds.outHeight;
boolean withinBounds = width <= maxWidth && height <= maxHeight;
if (!withinBounds) {
    int newWidth = calculateNewWidth(int width, int height);
    float sampleSizeF = (float) width / (float) newWidth;
    int sampleSize = Math.round(sampleSizeF);
    BitmapFactory.Options resample = new BitmapFactory.Options();
    resample.inSampleSize = sampleSize;
    bitmap = BitmapFactory.decodeFile(filePath, resample);
}

Answer

You are on the right track, however you are trying to do two things at once: read the file in and scale it to the appropriate size.

The first step is to read the file to a Bitmap slightly bigger than you require, using BitmapFactory.Options.inSampleSize to ensure that you do not consume excessive memory reading a large bitmap when all you want is a smaller thumbnail or screen resolution image.

The second step is to call Bitmap.createScaledBitmap() to create a new bitmap to the exact resolution you require.

Make sure you clean up after the temporary bitmap to reclaim its memory. (Either let the variable go out of scope and let the GC deal with it, or call .recycle() on it if you are loading lots of images and are running tight on memory.)

Categories
discuss

Finding file size and last modified of SFTP oldest file using Java

I’m using JSch to get files from an SFTP server, but I’m trying to figure out a way to only get the oldest file, and to make sure that it is not currently being written to. The way I imagine myself doing this is first finding which file in the specified remote folder is oldest. I would then check the file size, wait x seconds (probably about 10, just to be safe) and then check it again. If the file size has not changed, I download the file and process it. However, I have no idea how to do this! If anybody knows how to do this, or knows of something else that supports SFTP that has this built-in (I know Apache Commons does, but only does FTPS), it would be greatly appreciated.

Thanks in advance.

Answer

Turns out that this is entirely possible in JSch, the hardest part is simply finding the documentation. Code I used is below, hopefully somebody else will find it helpful! (I’m sure there are optimizations to be made, I know, I know. There are also variables that are defined elsewhere, but hopefully anybody that needs this will be able to figure them out!)

public static String oldestFile() {
    Vector list = null;
    int currentOldestTime;
    int nextTime = 2140000000; //Made very big for future-proofing
    ChannelSftp.LsEntry lsEntry = null;
    SftpATTRS attrs = null;
    String nextName = null;
    try {
        list = Main.chanSftp.ls("*.xml");
        if (list.isEmpty()) {
            fileFound = false;
        }
        else {
            lsEntry = (ChannelSftp.LsEntry) list.firstElement();
            oldestFile = lsEntry.getFilename();
            attrs = lsEntry.getAttrs();
            currentOldestTime = attrs.getMTime();
            for (Object sftpFile : list) {
                lsEntry = (ChannelSftp.LsEntry) sftpFile;
                nextName = lsEntry.getFilename();
                attrs = lsEntry.getAttrs();
                nextTime = attrs.getMTime();
                if (nextTime < currentOldestTime) {
                    oldestFile = nextName;
                    currentOldestTime = nextTime;
                }
            }
            attrs = chanSftp.lstat(Main.oldestFile);
            long size1 = attrs.getSize();
            System.out.println("-Ensuring file is not being written to (waiting 1 minute)");
            Thread.sleep(60000); //Wait a minute to make sure the file size isn't changing
            attrs = chanSftp.lstat(Main.oldestFile);
            long size2 = attrs.getSize();
            if (size1 == size2) {
                System.out.println("-It isn't.");
                fileFound = true;
            }
            else {
                System.out.println("-It is.");
                fileFound = false;
            }
        }
    } catch (Exception ex) {ex.printStackTrace();}
    return Main.oldestFile;
}
Categories
discuss

Android keyboard api

Does android expose an API or somesuch for the development of thirdparty keyboard applications? There are several existing apps which can replace the default input methods, however I cannot seem to find any information about it.

Answer

See Android Developers Blog post for creating an IME

Categories
discuss

How to set the color of an Android ScrollView fading edge?

I have an Android scrollview with a white background. The fading edge is a white translucent gradient. I would like to change it be black instead of white. I have a ListView in the same project with a white background that has a black fading edge by default, but I can’t find where (if anywhere) that was set.

Answer

Just found it out by trial and error.

Simply set android:background="@color/yourColor" for the <ScrollView>. It will set the shadow to the given colour.

Categories
discuss

Ruby methods within Javascript within HAML

I have a jQuery script that adds a new field to a form, and this field contains dynamic information from an array. The problem is that I can’t figure out how to add an array.each to populate the options of the select field within the javascript without breaking the HAML indentation and causing errors.

Here is my best attempt that does not work:

%script(type="text/javascript")  
  $('#mylink').click(function() {  
  $('#mylink').after('<select>  
  - myarray.each do |options|  
     <option value="#{options.id}">#{options.name}</option>  
  </select>);  
  )};

Also tried it with the :javascript filter with no luck.

Answer

Usually, if something is a pain in haml, it means you should refactor the the tricky bit to a helper or partial and call that.

// some_helper.rb
def new_snazzy_select_tag(options = [])
  select_tag 'tag_name_here', options.map { |option| [option.id, option.name] }
end

Also, you should use the :javascript filter to render javascript since it will put it in a script tag for you and allow indentation.

Lastly, you can use #{ruby_expression} anywhere in haml, including :javascript filters, which is very handy when you need to output the result of ruby expressions to places that are not directly contents of html elements.

// some_view.html.haml
:javascript
  $('#mylink').click(function() {  
    $('#mylink').after("#{escape_javascript new_snazzy_select_tag(myarray)}");
  };
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..