Skip to content

piclyf/Mobile-Feather-SDK-for-Android

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Aviary Android SDK Setup Guide

Contents

1 Introduction

This document will guide you through the creation of a sample application using the Aviary Android library (codename: Feather).

1.1 Prerequisites

The Aviary Android SDK supports Android 2.2+ as the minSdkVersion, but it must be compiled using Android 4.0 (API level 14) as the target sdk. This means that your application must have "Android 4.0" selected in the "Project Build Target" Eclipse panel.

This guide assumes that you already have the Android environment installed on your system and Eclipse with the required ADT plugin. See the Android documentation for installing and Eclipse if you need instructions on how to set up the Android environment.

You will also need an Aviary API key/secret pair to access the remote effect API. To sign up or learn more, please visit http://www.aviary.com/android-key.

2 Workspace setup

First, we'll need to import the 2 Eclipse projects into our workspace.

Open Eclipse and select "Import" from the file menu.

import project in eclipse

The import dialog will appear. From the list of import options, select "Existing Projects into Workspace," and then click "Next."

import project in eclipse

In the new dialog, click on the "Select archive file" radio button and then click the "Browse" button on the right. From here, select the aviaryfeather.zip file included with this document. Click on the "Finish" button at the bottom of the dialog. A new Android library project called "AviaryFeather" will be created in your current workspace. This is the required library project which you must include in your application if you want to use Aviary to manipulate images.

import project in eclipse

3 Sample Application

Next, we need to create an Android application in order to use the Aviary editor. You can see a real example of how to use the Aviary editor by opening the included sample-app.zip project.

Just import the sample application by following the same procedures described above, but select sample-app.zip at step 3.

A new project called "AviaryLauncher" will be created in your workspace. You can inspect this app to see a sample usage of the Aviary sdk.

The imported application should have all the references already set and it should be ready to use. If you want to include AviaryFeather in a different Android project or add it to a new one, follow the instructions in step 4; otherwise you can skip to step 5.

4 Include AviaryFeather in a new Application

If you don't want to use the included sample application to test Aviary, here's a step by step guide on how to include it in a new Android application.

4.1 Create a new Android project

Just create a new Android project as usual from Eclipse and select Android 4.0 in the Build Target Panel.

new eclipse project

Once the new project has been created, open the project properties and navigate to the "Android" section. Click the "Add..." button of the "Library" subsection and select "AviaryFeather" from the dialog.

project setup

Next, navigate to the "Java Build Path" section of the project properties dialog and click on "Add JARs..." button of the "Libraries" subsection.

project setup

From here, select the .jar file included in the "libs" folder of the AviaryFeather project (aviaryfeatherlibrary.jar).

project setup

You also need to add the android-support-v4.jar library. Please go to the official android support package page in order to obtain your copy of the jar file.

4.2 AndroidManifest.xml

Add some entries to the manifest file of your application.

Permissions

AviaryFeather requires internet and write access to external storage. To grant these permissions, add these entries inside the AndroidManifest.xml <manifest> tag:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

An additional permission is necessary if you want to turn on vibration feedback, but not mandatory:

<uses-permission android:name="android.permission.VIBRATE" />

This permission will enable the vibration feedback on some tool components, for a better user experience. Omit this permission if you don't want the vibration feedback.

Activity declaration

As mentioned above, the Aviary sdk supports Android 2.2 as the minimum Android version, so the "uses-sdk" xml node of your manifest should look like this:

<uses-sdk android:minSdkVersion="8" />

Then, inside the <application> tag, add a reference to the FeatherActivity:

<activity
    android:name="com.aviary.android.feather.FeatherActivity"
    android:configChanges="orientation|keyboardHidden"
    android:screenOrientation="unspecified"
    android:hardwareAccelerated="true"
    android:largeHeap="true"
    android:theme="@style/FeatherDefaultTheme.Custom" />

And a reference to the plugins receiver is also necessary:

<receiver
    android:name="com.aviary.android.feather.receivers.FeatherSystemReceiver"
    android:exported="true"
    android:process=":feather_system_receiver" >
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_ADDED" />
            <action android:name="android.intent.action.PACKAGE_REMOVED" />
            <action android:name="android.intent.action.PACKAGE_REPLACED" />
            <data android:scheme="package" />
        </intent-filter>
</receiver>

If you plan to enable the High resolution image process ( see section 10 ) you also must add this entry to the AndroidManifest:

    <!-- Required for the hi-res image processing -->
    <!-- authorities can have the value you prefer -->
    <provider 
        android:name="com.aviary.android.feather.library.providers.FeatherContentProvider"
        android:exported="false"
        android:authorities="com.aviary.launcher.HiResProvider">
    </provider>

Note that the "android:autorities" is arbitrary, you can use the string value you prefer.

4.3 Theme and Styles

The android:theme entry in the manifest file is also required for Aviary to work properly, so add an entry to your themes.xml file (if you don't have one, create a new file called themes.xml in your res/values folder):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="FeatherDefaultTheme.Custom" parent="FeatherDefaultTheme" />
</resources>

By default, this entry will use the default Aviary theme. If you'd like to customize the editor's UI, you can do that simply by adding entries to your "FeatherDefaultTheme.Custom" style. Check out the styles.xml file included in AviaryFeather/res/values for the list of available styles.

Note that many UI elements depend on both the styles.xml and config.xml files included. The styles.xml file declares the UI components' general appearance, while in the config.xml file you'll find component specific dimensions (like for text or lists) and most of the properties for customizing Aviary's panel behavior.

5 Invoke Feather

If you're calling Aviary from a new application, you'll need to add the below code in order to start the editor. Otherwise (if you're using the demo application), you can find this code inside the MainActivity.java file.

In order to invoke Aviary from your activity, you need to pass some parameters to the FeatherActivity. Here's an example of how to invoke the new activity:

// Create the intent needed to start feather
Intent newIntent = new Intent( this, FeatherActivity.class );
// set the source image uri
newIntent.setData( uri );
// pass the required api key ( http://developers.aviary.com/ )
newIntent.putExtra( "API_KEY", "xxx" );
// pass the uri of the destination image file (optional)
// This will be the same uri you will receive in the onActivityResult
newIntent.putExtra( "output", Uri.parse( "file://" + mOutputFile.getAbsolutePath() ) );
// format of the destination image (optional)
newIntent.putExtra( "output-format", Bitmap.CompressFormat.JPEG.name() );
// output format quality (optional)
newIntent.putExtra( "output-quality", 85 );
// you can force feather to display only a certain tools
// newIntent.putExtra( "tools-list", new String[]{"ADJUST", "BRIGHTNESS" } );

// enable fast rendering preview
newIntent.putExtra( "effect-enable-fast-preview", true );

// limit the image size
// You can pass the current display size as max image size because after
// the execution of Aviary you can save the HI-RES image so you don't need a big
// image for the preview
// newIntent.putExtra( "max-image-size", 800 );

// HI-RES
// You need to generate a new session id key to pass to Aviary feather
// this is the key used to operate with the hi-res image ( and must be unique for every new instance of Feather )
// The session-id key must be 64 char length
String mSessionId = StringUtils.getSha256( System.currentTimeMillis() + API_KEY );
newIntent.putExtra( "output-hires-session-id", mSessionId );	

// you want to hide the exit alert dialog shown when back is pressed
// without saving image first
// newIntent.putExtra( "hide-exit-unsave-confirmation", true );

// ..and start feather
startActivityForResult( newIntent, ACTION_REQUEST_FEATHER );

5.1 Intent parameters

Here's a description of the required parameters:

Uri

(intent data) This is the source URI of the image to be used as input by Aviary

API_KEY

An api key IS REQUIRED to use remote filters. Please visit http://www.aviary.com/android-key for more information on how to obtain your api key and secret

output

This is the uri of the destination file where Aviary will write the result image

output-format

Format of the output file (jpg or png)

output-quality

Quality of the output image (required only if output-format is jpeg). 0 to 100

effect-enable-fast-preview

Depending on the current image size and the current user device, some effects can take longer than expected to render the image. Passing in the caller intent this flag as boolean "true" the effect panel will no longer use the default progress modal dialog while rendering an effect but instead will use a small "loading" view while rendering a small image preview. User will almost immediately see the small preview while the full size image is being processed in background. Once the full size image is processed, it will replace the small preview image. The default behavior is to enable this feature only on fast devices (fast enough to allow the small preview to be rendered immediately). Pass "false" if you want to force the "progress modal" rendering model. No small preview, only a modal progress bar while rendering the image.

tools-list

If specified in the extras of the passed intent, it will tell Aviary to display only certain tools. The value must be a String[] array and the available values are:

SHARPNESS, BRIGHTNESS, CONTRAST, SATURATION, EFFECTS, RED_EYE, CROP, WHITEN, DRAWING, 
STICKERS, TEXT, BLEMISH, MEME, ADJUST, ENHANCE

hide-exit-unsave-confirmation

When the user clicks the back button and the image contains unsaved data, a confirmation dialog appears by default. Setting this flag to true will hide that confirmation and the application will terminate without a warning to the user.

effect-enable-external-pack

By default feather allows users to download and install external filters packs from the android market. If you want to disable this feature you can pass this extra boolean to the launching intent as "false". The default behavior is to enable the external filters.

stickers-enable-external-pack

By default feather allows users to download and install external stickers packs from the android market. If you want to disable this feature you can pass this extra boolean to the launching intent as "false". The default behavior is to enable the external stickers.

max-image-size

By default feather will resize the loaded image according to the device memory. If you want to change the maximum image size limit you can pass this key to the extra bundle. But keep in mind that the available memory for the current application is shared between your host application and the aviary editor, so don't use a too large image size otherwise the system will throw an OutOfMemoryError. If you're planning to enable the hi-res output too, I strongly suggest to set the preview image size as little as possible.

output-hires-session-id

If you want to enable the high resolution image process, once FeatherActivity has completed ( but eventually also during its execution ), you need to pass a unique session id to the calling Intent. The session id string must be unique and must be 64 chars length

5.2 Result parameters

Once the user clicks "save" in the Feather activity, the "onActivityResult" of your Activity will be invoked, passing back "ACTION_REQUEST_FEATHER" as requestCode. The Uri data of the returned intent will be the output path of the result image:

@Override
public void onActivityResult( int requestCode, int resultCode, Intent data ) {
    if( resultCode == RESULT_OK ) {
        switch( requestCode ) {
            case ACTION_REQUEST_FEATHER:
                Uri mImageUri = data.getData();
                break;
       }
    }
}

6 Extras

6.1 Stickers

The sample application includes just a couple of demo stickers which will be shown as a default pack. In addition, users can install more packs from the market and they will be added automatically into the stickers panel. If you want to use default stickers, just make sure to create a folder
"stickers" into your "asset" folder. Then just include in that folder all the .png stickers you want to include as default pack. Otherwise, if you don't want to include default stickers, you need to change a value in the file plugins.xml, included in the res/values folder:

Change the line:

<integer name="is_sticker">1</integer>

into:

<integer name="is_sticker">0</integer>

This will mean that users won't see any default sticker pack, but instead only a link to download packs from the marketplace.

stickers

6.2 Other configurations

Inside the AviaryFeather/res/values folder is a config.xml file. This file contains some application default values and can be modified before compilation.

Here is the description for tool-specific configuration variables:

Orientation Tool

feather_adjust_tool_anim_time Defines the duration of the rotation/flip animation.

feather_adjust_tool_reset_anim_time Defines the reset animation duration (i.e., when the user clicks the cancel/back button).

feather_adjust_tool_enable_3d_flip If device is running Android 4.x you can enable a flip animation in 3D style by setting this param to 1.

Brightness, Contrast, Saturation

feather_brightness_live_preview Enable/Disable the live preview while the wheel component is scrolling. Default is enabled

Text Tool

feather_text_minSize Minimum text size allowed when user is resizing the text rect.

feather_text_defaultSize Initial text size when a new text is added to the canvas.

feather_text_padding Padding space between the text edges and the move/resize area rectangle.

feather_text_highlight_stroke_width Stroke with of the move/resize rect.

feather_text_highlight_stroke Stroke color of the move/resize rect.

feather_text_highlight_stroke_down Stroke color of the move/resize rect on pressed state.

feather_text_highlight_ellipse Move/resize round rectangle ellipse size.

feather_text_selected_color Fill color of the move/resize rectangle on pressed state.

feather_text_fill_colors An array of all the available colors available for the text tool.

feather_text_stroke_colors This array must have the same length of the feather_text_fill_colors. For every fill color you can specify a different stroke color.

Crop Tool

feather_crop_min_size Minimum area size while resizing the crop area.

feather_crop_allow_inverse If value is 1 allow user to invert the current crop area with a simple click on the crop rect itself.

feather_crop_highlight Stroke color of the crop area.

feather_crop_highlight_down Stroke color of the crop area when pressed.

feather_crop_highlight_outside Fill color of the inactive area. The one outside the crop rect.

feather_crop_highlight_outside_down Inactive area color when crop rect is pressed.

feather_crop_highlight_stroke_width Stroke size of the crop area.

feather_crop_highlight_internal_stroke_width Stroke size of the internal crop lines.

feather_crop_highlight_internal_stroke_alpha Alpha (0 - 255) of the internal lines.

feather_crop_highlight_internal_stroke_alpha_down Alpha of the internal lines when crop rect is pressed.

Feather by default comes with a predefined number of crop ratios available to the user (original, custom, square, 4:3, etc). If you want to change them, read this carefully. There are 2 xml entries responsible for this: feather_crop_names and feather_crop_values.

feather_crop_values Defines the crop predefined ratio for every button.

feather_crop_names Defines the labes for the button.

Every item in the feather_crop_values defines how the crop rect will be presented. For instance, the following item:

<item>3:2</item>

will create a crop area restricted in its proportions to 3 by 2. Or the following one:

<item>-1:-1</item>

will create a crop area restricted to the original image width and height.

All the previous examples will create a crop area with restricted proportions. If you want to allow the user to have a crop rect without limitations, just use an item like this:

<item>0:0</item>

Red Eye, Whiten, Blemish and Draw Tool

feather_brush_sizes An array containing all the brush size available for the user.

Draw Panel

feather_brush_softValue defines the softness value for the brush pen.

feather_default_colors defines the available brush colors.

Stickers

feather_sticker_highlight_minsize Minimum size of the sticker while resizing.

feather_sticker_highlight_padding Padding of the highlight area from the sticker edges.

feather_sticker_highlight_stroke_width Stroke size of the highlight area.

feather_sticker_highlight_ellipse Ellipse size of the highlight area borders.

feather_sticker_highlight_stroke Highlight stroke color.

feather_sticker_highlight_stroke_down Highlight stroke color when pressed.

feather_sticker_highlight_outline Highlight fill color.

feather_sticker_highlight_outline_down Highlight fill color when pressed.

6.3 UI Customization

You can customize almost every aspect of the application by editing the styles.xml file included in the res folder.

7 Localization

Android is really smart regarding localization. Localizing resources and strings is very easy.

Here are the instructions to create a new language for all the label messages of Aviary (let's say we want to add Italian support):

  • Go into the AviaryFeather/res folder

  • Create a new folder "values-it".

  • Copy the file res/values/strings.xml into the res/values-it folder.

  • Open the res/values-it/strings.xml file with any text editor and translate all the strings within the <string></string> tag. For instance, the original version of the string "Save" is:

    <string name="save">Save</string>

  • in your localized strings.xml file it will be:

    <string name="save">Salva</string>

Now just clean and recompile your application. If your device has set Italian as the default language, you will see Aviary in Italian.

For a more detailed tutorial about Android localization, you can refer to this tutorial.

The current version of the SDK comes with a bunch of localized languages, you can find them inside the "res" folder of the Feather project.

8 Proguard

If your application is compiled using proguard you need to update your proguard.cfg file according to the proguard.cfg file included in the sample application.

9 Crash Report

The crash reporting tool provided with the standard android market is often useless due to the minimum amount of informations provided. If you want to report to us of crashes occurred in our application we suggest you to include in your application an external crash report tool like ACRA

10 Hi-Resolution Image Editing

By default feather works on a medium resolution image, this to speed up the performance of the editor. But you can also save the hi-res version of the image:

  • In the calling Intent you must pass an extra string, the hi-res session id in this way:

      final String session_name = StringUtils.getSha256( System.currentTimeMillis() + API_KEY );
      newIntent.putExtra( "output-hires-session-id", session_name );
    

    The session string must be unique and must be 64 char lenght. Once feather starts it will start collecting informations of every action performed on the image and will store those actions in the internal ContentProvider ( remember to add the provider tag to the AndroidManifest first! ).

  • Once your activity will call the "onActivityResult" method you can process the HD image.

    First create a new file where the HD image will be stored

      File destination = getNextFileName();
    

    Initialize the session instance

      FeatherContentProvider.SessionsDbColumns.Session session = null;
    

    session_name is the same session string you passed in the calling intent

      Uri sessionUri = FeatherContentProvider.SessionsDbColumns.getContentUri( session_name );
    

    This query will return a cursor with the informations about the given session

      Cursor cursor = getContentResolver().query( sessionUri, null, null, null, null );
      
      if ( null != cursor ) {
      	session = FeatherContentProvider.SessionsDbColumns.Session.Create( cursor );
      	cursor.close();
      }
    

    At this point you will have a Session object with the following informations:

    • session.id, the internal id of the session
    • session.name, the session 64 char wide value
    • session.ctime, the session creation time
    • session.file_name, the original image used for editing ( the same you passed in the calling Intent )

    Now you must query the ContentProvider to get the list of actions to be applied on the original image:

      Uri actionsUri = FeatherContentProvider.ActionsDbColumns.getContentUri( session.session );
      Cursor cursor = getContentResolver().query( actionsUri, null, null, null, null );
    

    And finally the steps to load, apply the actions and save the HD image. ( obviously these steps should be performed in a separate thread, like an AsyncTask):

    Create an instance of MoaHD class

      MoaHD moa = new MoaHD();
    

    Load the image in memory, note that the srcPath can be either a string absolute path or an int ( see ParcelFileDescriptor.getFd() )

      // result will be Error.NoError is load completed succesfully
      MoaHD.Error result = moa.load( srcPath );
    

    Then, for every row in the actions cursor, apply the action to the moa instance:

      if( result == MoaHD.Error.NoError ){
      	do {
      		// utility to get the action object from the current cursor
      		Action action = Action.Create( cursor );
      		moa.applyActions( action.getActions() );
      	} while( cursor.moveToNext() );
      }
    

    Finally you can save the output image. dstPath must be an absolute string path:

      result = moa.save( dstPath );
      // if image was saved result will be Error.NoError
      if( result == Error.NoError ){
      	// unload the image from memory
      	moa.unload();
      }
      moa.dispose();
    

    ...And remember to close the cursor:

      cursor.close();