The New Relic Android App Has a Cool UI Trick, and You Can Add It to Your Own Apps

We’re really excited about today’s launch of the New Relic Android app, so we wanted to give you a little background on one of the app’s coolest features, and show you how to incorporate it into your own Android apps.

As an app developer you might wonder what you should show on the screen while the app is downloading real-time data. Should it be a spinner over a ‘loading…’ message? Or maybe a cute cat gif? While some developers opt to show data that was on the screen the last time the view was loaded, at New Relic we made a conscious decision not to display outdated/old data on the screen because we felt it wasn’t valuable for users to see data unless it was current. With this in mind we decided to create something a little different while we waited for fresh data to download from the server.

Our solution to the ‘what to display while data is downloading’ question ended up being to create a blurred version of the view from the last time it was loaded, which seemed like a nice way to show users that the view wasn’t interactive (yet), and still ease them into what we were about to present. Here’s how to create the effect in your own Android apps in 5 easy steps.

android blur

Step 1. Convert the View to a Bitmap

You will need to have a reference to the View and pass it to a method that does the conversion to a bitmap:


public Bitmap createViewBitmap(View view){
Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Cancas(b);
view.draw©;
return b;
}

Step 2. Add Renderscript support

First, you need to install the Renderscript libs into your build. This is only a couple of lines of code with Gradle. (As an aside, if you’ve not switched over to Gradle yet you should do it as soon as possible)

Here is the Gradle code to include the Renderscript library. Put this in the Android block of your build.gradle file:


android{
  compileSdkVersion 19
  buildToolsVersion “19.0.3”

  defaultConfig {
    minSdkVersion 14
    targetSdkVersion 19
    renderscriptTargetApi 19
    renderscriptSupportMode true
  }

}

Step 3. Apply the blur effect

Once you have access to the Renderscript library, you need a method that applies the blur. Something else you may want to consider is what the app should do if the Renderscript isn’t available or fails for some reason. In this case it might be a good idea to wrap the method in a try/catch block and substitute a different effect such as grayscale to indicate that the data is not active:



   public synchronized static Bitmap blurImage(Bitmap bitmap, Context context) {
    try {
      // blur the image 
      final RenderScript rs = RenderScript.create(context);
      final Allocation input =
          Allocation.createFromBitmap(rs, bitmap, Allocation.MipmapControl.MIPMAP_NONE,
              Allocation.USAGE_SCRIPT);
      final Allocation output = Allocation.createTyped(rs, input.getType());
      final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
      script.setRadius(14f);
      script.setInput(input);
      script.forEach(output);
      output.copyTo(bitmap);
    } catch (RuntimeException ex) {
      // if renderscript fails on users device we will return a black and white image
      NRConfig.logMessageWithCollector("Renderscript Library not found in this build");
      if (null != bitmap) {
        Bitmap bmpGrayscale =
            Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.RGB_565);
        Canvas c = new Canvas(bmpGrayscale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        c.drawBitmap(bitmap, 0, 0, paint);
        return bmpGrayscale;
      }
    }
    return bitmap;
  }

Step 4. Save the blurred image

Now that you have your blurred image you’ll want to save it to the device so you can access it the next time you are waiting for fresh data from your server. You’ll need a file name and a location to save the image to. It might also be a good idea to tuck this into an asynchronous task so you don’t tie up the UI thread while writing to the device:


 public synchronized static void saveImageAsPNGToAppStoreage(final String filename,
      final Bitmap bitmap, final Context appContext) {

    new AsyncTask<Void, Void, Void>() {
      @Override
      protected Void doInBackground(Void... voids) {
        try {
          ByteArrayOutputStream bytes = new ByteArrayOutputStream();
          bitmap.compress(Bitmap.CompressFormat.PNG, 40, bytes);

          ContextWrapper cw = new ContextWrapper(appContext);
          // path to /data/data/yourapp/app_data/NrImageDir
          File directory = cw.getDir(IMAGE_DIRECTORY, Context.MODE_PRIVATE);
          // Create imageDir
          File f = new File(directory + File.separator + filename + ".png");

          f.createNewFile();

          FileOutputStream fo = new FileOutputStream(f);
          fo.write(bytes.toByteArray());
          fo.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
        return null;
      }
    }.execute((Void[]) null);
  }

5. Retrieve your blurred image

The final step is to retrieve your blurred image from the device while you are waiting for your fresh data to arrive:


  public Bitmap getPNGImageFromAppStorage(Context appContext, String fileName) {
    final ContextWrapper cw = new ContextWrapper(appContext);
    // path to /data/data/yourapp/app_data/NrImageDir
    File directory = cw.getDir(IMAGE_DIRECTORY, Context.MODE_PRIVATE);
    return BitmapFactory.decodeFile(directory.getPath() + File.separator + fileName + ".png");
  }

That’s it! Good luck creating blurred views for your own Android apps! Download and start using the New Relic Android app today.

larry@newrelic.com'

Larry Wegener has been developing Android applications since 2010. After receiving his degree from DePaul University, he began developing mobile apps professionally first for the iOS platform. He quickly moved to the Android platform because of client demand and has been developing Android applications ever since. He has developed apps for Postcard on the Run, Food Network, Google and Intel. He’s currently developing Android applications for New Relic at their Portland Oregon office after a lifetime of living in the Upper Midwest. He can be contacted at larry@newrelic.com View posts by .

Interested in writing for New Relic Blog? Send us a pitch!