Features

Updated at:
Copy as MD

Use Queen SDK for Android to integrate retouching, face shaping, body shaping, makeup, filters, stickers, and AI-powered effects into your Android app.

Before you begin

  • If you are upgrading Queen SDK from V1.X.X to V2.0.0 or later, note the following:

    • The package name of the Java API has changed from com.taobao.android.libqueen to com.aliyun.android.libqueen.

      • Re-submit a request on the Create Application and Bind License page to get a new license key and license file. Set Request_License_File in the title. Alibaba Cloud will send you the license key and file within two business days. Then, log on to the ApsaraVideo Live or VOD console, and choose SDK Management > My Licenses in the left-side navigation pane to create an application and bind the license.

  • For information about how to integrate Queen SDK for Android, see References.

  • For answers to frequently asked questions, see FAQ about Queen SDK.

Resource download

Important
  1. The built-in resource download service in Queen SDK is a temporary service provided for demonstration purposes only. Its availability and effectiveness are not guaranteed and it cannot be used in production applications.

  2. For production use, host your resources on your own server. Alibaba Cloud does not provide resource download services or support for managing this infrastructure.

Specify custom resource URLs

  1. If you use queen_menu, set the resource download URL with the following code:

    // Set the download URL for each resource type before menu components are initialized.
    // QueenMaterial is a static singleton — set it early.
    // MaterialType valid values: MODEL, STICKER, LUT, MAKEUP, BACKGROUND, and FACE_EFFECTS.
    // materialUrl: the URL of the resource package (ZIP file in the root directory).
    // The system automatically scans and loads resources from the decompressed folder.
    QueenMaterial.getInstance().setMaterialUrl(MaterialType materialType, String materialUrl);
  2. For custom menu widgets, use the full download flow:

    // Step 1: Initialize the resource download handler.
    QueenMaterial.getInstance().init(context);
    
    // Step 2: Set the download URL for each resource type.
    // Call this before requestMaterial, preferably immediately after init.
    // MaterialType valid values: MODEL, STICKER, LUT, MAKEUP, BACKGROUND, and FACE_EFFECTS.
    // materialUrl: the URL of the resource package (ZIP file in the root directory).
    // The system automatically scans and loads resources from the decompressed folder.
    QueenMaterial.getInstance().setMaterialUrl(MaterialType materialType, String materialUrl);
    
    // Step 3: Register a download listener. Use the onReady callback to apply resources by type.
    // The SDK appends the local path automatically.
    QueenMaterial.getInstance().setCallback(new QueenMaterial.OnMaterialCallback() {
    
        @Override
        public void onReady(QueenMaterial.MaterialType materialType) {
            // Called on a non-UI thread when the download completes.
            // Close any loading UI and trigger your business logic here.
    
            // Example: apply a sticker after its resources are downloaded.
            String stickerName = "1"; // Relative path of the sticker.
            String stickerPath = QueenMaterial.getInstance().getMaterialPath(QueenMaterial.MaterialType.STICKER) + File.separator + stickerName;
            engine.addMaterial(stickerResPath);
        }
    
        @Override
        public void onProgress(QueenMaterial.MaterialType materialType, int currentSize, int totalSize, float progress) {
            // Called on a non-UI thread. Update the download progress UI here.
        }
    
        @Override
        public void onError(QueenMaterial.MaterialType materialType) {
            // Called on a non-UI thread. Close the loading UI and prompt the user
            // to check network connectivity and available disk space.
        }
    
    });
    
    // Step 4: Start the download.
    QueenMaterial.getInstance().requestMaterial(MaterialType materialType);

Integrate the SDK for basic retouching

  1. Create a QueenEngine instance and configure texture and view parameters.

    QueenEngine engine;
    try {
        com.aliyun.android.libqueen.QueenConfig config = new com.aliyun.android.libqueen.QueenConfig();
        // true: render output to the OpenGL display area. Default: false.
        config.toScreen = false;
        // true: enable log debugging. Default: false.
        // Enable only in Debug builds to avoid performance degradation.
        config.enableDebugLog = false;
        // true: create an OpenGL context for this QueenEngine instance. Default: false.
        config.withContext = false;
        // true: create a separate thread. Default: false.
        config.withNewGlThread = false;
        if (withContext || withNewGlThread) {
            // Share the current thread's OpenGL context with the new QueenEngine thread.
            if (Build.VERSION.SDK_INT >= 21) {
              config.shareGlContext = EGL14.eglGetCurrentContext().getNativeHandle();
            } else {
              config.shareGlContext = EGL14.eglGetCurrentContext().getHandle();
            }
        }
        // Pass an Android.content.Context object to initialize QueenEngine.
        // The second parameter applies the configuration set above.
        engine = new QueenEngine(mContext, config);
    } catch (InitializationException e) {
        e.printStackTrace();
    }
    
    // Set the input texture for retouching.
    // The fourth parameter indicates whether the input texture type is OES.
    engine.setInputTexture(textureId, textureWidth, textureHeight, true);
    
    // Optional: get the retouching output texture for use in other pipelines.
    // Set keepInputDirection to true in autoGenOutTexture and updateOutTexture
    // to keep the output in the same orientation as the input.
    Texture2D outTexture = engine.autoGenOutTexture(true);
    
    // Set the viewport size.
    engine.setScreenViewport(0, 0, viewWidth, viewHeight);
    // Enable log output and debugging. Enable only in Debug builds to avoid performance degradation.
    engine.enableDebugLog();
  2. Configure basic retouching parameters.

    // Enable skin whitening.
    engine.enableBeautyType(BeautyFilterType.kSkinWhiting, true);
    // Set the skin whitening level. Valid values: 0 to 1.
    engine.setBeautyParam(
        BeautyParams.kBPSkinWhitening, 
        0.3f
    );
    /**
    * Enable skin smoothing and image sharpening.
    * The third parameter sets the retouching mode:
    *   kBMSkinBuffing_Natural — more natural results with more detail retained.
    *   kBMSkinBuffing_Strong — more pronounced effects with more detail removed.
    */
    engine.enableBeautyType(BeautyFilterType.kSkinBuffing, true, BeautyFilterMode.kBMSkinBuffing_Natural);
    // Set the skin smoothing level. Valid values: 0 to 1.
    engine.setBeautyParam(BeautyParams.kBPSkinBuffing, 0.6f);
    // Set the image sharpening level. Valid values: 0 to 1.
    engine.setBeautyParam(BeautyParams.kBPSkinSharpen, 0.2f);
  3. Render the texture.

    // Get the OES texture transformation matrix from SurfaceTexture.
    float[] transformMatrix = new float[16];
    mSurfaceTexture.updateTexImage();
    mSurfaceTexture.getTransformMatrix(transformMatrix);
    
    // Render to the current view.
    // If license authentication fails or all effects are disabled, Queen SDK skips rendering.
    int retCode = engine.renderTexture(transformMatrix);
    
    // QUEEN_INVALID_LICENSE(-9): license authentication failed.
    // QUEEN_NO_EFFECT(-10): all effects are disabled.
    // In either case, render the texture manually.
    // See the sample project in the "References" section of the "Integrate Queen SDK for Android" topic.
    if (retCode == -9 || retCode == -10) {
        mFrameGlDrawer.draw(transformMatrix, mOESTextureId, true);
    }
  4. Release the engine.

    // Release engine resources.
    engine.release();

Advanced features

Before using advanced features — including advanced retouching, face shaping, body shaping, makeup, filters, and stickers — call updateInputTextureBufferAndRunAlg to feed the algorithm with frame data.

if (mUseTextureBuffer) { // Run the algorithm using texture data.
  engine.updateInputTextureBufferAndRunAlg(
      mCamera.inputAngle, mCamera.outAngle,
      mCamera.flipAxis, false);
} else {
  // Run the algorithm using raw frame image data.
  engine.updateInputDataAndRunAlg(
    imageData,          // Frame image stream.
    ImageFormat.NV21,   // Frame image format.
    imageWidth,         // Frame width.
    imageHeight,        // Frame height.
    0,                  // Image stride in bytes per row. Default: 0 (unit: pixel).
    mCamera.inputAngle, // Input frame rotation angle. See the sample project for the formula.
    mCamera.outAngle,   // Output frame rotation angle. See the sample project for the formula.
    mCamera.flipAxis    // Output frame flip axis: 0 = no flip, 1 = x-axis, 2 = y-axis.
  );
}

Advanced retouching

// Enable advanced retouching.
engine.enableBeautyType(BeautyFilterType.kFaceBuffing, true);
// Set the smile line removal level. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPNasolabialFolds, 0.3f); 
// Set the eye-bag removal level. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPPouch, 0.3f); 
// Set the teeth whitening level. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPWhiteTeeth, 0.2f); 
// Set the lipstick level. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPLipstick, 0.2f); 
// Set the blush level. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPBlush, 0.2f);
// Set the eye brightening level. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPBrightenEye, 1.0f);
// Set the rosy cheeks level. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPBlush, 1.0f);
// Set the lipstick color. Valid values: -0.5 to 0.5. Set color, saturation, and brightness together.
// Color values: ochre=-0.125, pink=-0.1, vintage red=0.0, magenta=-0.2, true red=-0.08,
//               orange red=0.0, purple=-0.42, orange=0.125, yellow=0.25
engine.setBeautyParam(BeautyParams.kBPLipstickColorParam, 0.0f);
// Set the lipstick saturation. Valid values: 0 to 1. Set color, saturation, and brightness together.
// Saturation values: ochre=0.25, pink=0.125, vintage red=1.0, magenta=0.35, true red=1.0,
//                    orange red=0.35, purple=0.35, orange=0.25, yellow=0.45
engine.setBeautyParam(BeautyParams.kBPLipstickGlossParam, 0.0f);
// Set the lipstick brightness. Valid values: 0 to 1. Set color, saturation, and brightness together.
// Brightness values: ochre=0.4, pink=0.0, vintage red=0.2, magenta=0.0, true red=0.0,
//                    orange red=0.0, purple=0.0, orange=0.0, yellow=0.0
engine.setBeautyParam(BeautyParams.kBPLipstickBrightnessParam, 1.0f);
// Set the wrinkle removal level. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPWrinkles, 0.2f);
// Set the skin brightening level. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPBrightenFace, 0.2f);
// Enable the hue, saturation, and value (HSV) color model.
engine.enableBeautyType(BeautyFilterType.kHSV,true);
// Set the saturation level. Valid values: -1 to 1.
engine.setBeautyParam(BeautyParams.kBPHSV_SATURATION,0.2f);
// Set the contrast level. Valid values: -1 to 1.
engine.setBeautyParam(BeautyParams.kBPHSV_CONTRAST,0.2f);

Face effects

// Enable the pixelation effect.
engine.enableBeautyType(BeautyFilterType.kBTEffectMosaicing,true);
engine.setBeautyParam(BeautyParams.kBPEffects_Mosaicing,0.45f);

Face shaping

/**
 * Enable face shaping.
 * Parameter 2: enable face shaping (true/false).
 * Parameter 3: enable debugging (true/false).
 * Parameter 4: shaping mode — kBMFaceShape_Baseline, kBMFaceShape_Main, kBMFaceShape_High,
 *              or kBMFaceShape_Max (intensity increases in this order).
 */
engine.enableBeautyType(BeautyFilterType.kFaceShape, true, false, BeautyFilterMode.kBMFaceShape_Main);
/**
 * Cheekbones. Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeCutCheek, 0.0f);
/**
 * Cheekbone narrowing. Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeCutFace, 0.0f);
/**
 * Face slimming. Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeThinFace, 0.0f);
/**
 * Face length. Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeLongFace, 0.0f);
/**
 * Chin shortening. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeLowerJaw, 0.0f);
/**
 * Chin lengthening. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeHigherJaw, 0.0f);
/**
 * Chin slimming. Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeThinJaw, 0.0f);
/**
 * Jaw slimming. Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeThinMandible, 0.0f);
/**
 * Eye enlargement. Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeBigEye, 0.0f);
/**
 * Canthus shaping (style 1). Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeEyeAngle1, 0.0f);
/**
 * Eye distance. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeCanthus, 0.0f);
/**
 * Eye distance (wider). Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeCanthus1, 0.0f);
/**
 * Canthus shaping (style 2). Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeEyeAngle2, 0.0f);
/**
 * Eye height. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeEyeTDAngle, 0.0f);
/**
 * Nose slimming. Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeThinNose, 0.0f);
/**
 * Nasal alar slimming. Valid values: 0 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeNosewing, 0.0f);
/**
 * Nose length. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeNasalHeight, 0.0f);
/**
 * Nose tip length. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeNoseTipHeight, 0.0f);
/**
 * Lip width. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeMouthWidth, 0.0f);
/**
 * Lip size. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeMouthSize, 0.0f);
/**
 * Lip height. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeMouthHigh, 0.0f);
/**
 * Philtrum. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typePhiltrum, 0.0f);
/**
 * Hairline. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeHairLine, 0.0f);
/**
 * Smile intensity. Valid values: -1 to 1.
 */
engine.updateFaceShape(FaceShapeType.typeSmile, 0.0f);

Body shaping

/**
* Enable body shaping.
* Parameter 2: enable body shaping (true/false).
* Parameter 3: enable debugging (true/false).
*/
engine.enableBeautyType(BeautyFilterType.kBodyShape, true, false);
/**
* Whole body. Valid values: -1 to 1.
*/
engine.updateBodyShape(BodyShapeType.kFullBody, 1.0f);
/**
* Small head. Valid values: -1 to 1.
*/
engine.updateBodyShape(BodyShapeType.kSmallHead, 1.0f);
/**
* Thin legs. Valid values: -1 to 1.
*/
engine.updateBodyShape(BodyShapeType.kThinLeg, 1.0f);
/**
* Long legs. Valid values: -1 to 1.
*/
engine.updateBodyShape(BodyShapeType.kLongLeg, 1.0f);
/**
* Neck elongation. Valid values: -1 to 1.
*/
engine.updateBodyShape(BodyShapeType.kLongNeck, 1.0f);
/**
* Slim waist. Valid values: -1 to 1.
*/
engine.updateBodyShape(BodyShapeType.kThinWaist, 1.0f);
/**
* Breast enhancement. Valid values: -1 to 1.
*/
engine.updateBodyShape(BodyShapeType.kEnhanceBreast, 1.0f);
/**
* Thin arms. Valid values: -1 to 1.
*/
engine.updateBodyShape(BodyShapeType.kThinArm, 1.0f);

Makeup

Enable makeup.

// Enable makeup.
// Parameter 2: enable makeup (true/false).
// Parameter 3: enable debugging (true/false).
// Parameter 4: makeup mode (applies to eyebrows only).
//   kBMFaceMakeup_High — high eyebrow deformation level.
//   kBMFaceMakeup_Baseline — low eyebrow deformation level.
engine.enableBeautyType(BeautyFilterType.kMakeup, true, false, BeautyFilterMode.kBMFaceMakeup_Baseline);

// Set makeup material parameters.
// Parameter 1: makeup type.
// Parameter 2: paths to makeup materials. Use a path relative to the assets folder
//              (for example, /makeup/peach makeup.png) or an absolute path.
// Parameter 3: blend mode for applying makeup to the face.
// Parameter 4: reserved.
engine.setMakeupImage(MakeupType.kMakeupBlush,
           new String[]{""},  
           BlendType.kBlendCurve, 15);
/**
* kMakeupWhole applies a single material to the entire face but does not allow
* per-feature adjustments.
*
* For SDK versions later than V1.4.0, use mixed makeup to adjust individual facial features.
* The following presets are available:
*
* 1. Tipsy makeup:
*   Eye shadow: makeup/eyeshadow/naichazong.2.31.png, transparency 0.7
*   Eyelashes:  makeup/eyelash/yesheng.2.31.png, transparency 0.5
*   Blush:      makeup/blush/weixun.2.31.png, transparency 0.8
*   Eyeliner:   makeup/eyeliner_292929/wenrou.2.31.png, transparency 0.5
*   Lipstick:   makeup/mouth_wumian/standout.2.31.png, transparency 0.5
*   Highlight:  makeup/highlight/highlight.2.12.png, transparency 0.4
*
* 2. Freckle makeup:
*   Eye shadow: makeup/eyeshadow/taohuafen.2.31.png, transparency 0.7
*   Eyelashes:  makeup/eyelash/yesheng.2.31.png, transparency 0.5
*   Blush:      makeup/blush/cool.2.31.png, transparency 0.8
*   Eyeliner:   makeup/eyeliner_292929/guima.2.31.png, transparency 0.5
*   Lipstick:   makeup/mouth_yaochun/nanguase.2.31.png, transparency 0.5
*   Highlight:  makeup/highlight/highlight.2.12.png, transparency 0.4
*
* 3. Lively makeup:
*   Eye shadow: makeup/eyeshadow/tianchengse.2.31.png, transparency 0.7
*   Eyelashes:  makeup/eyelash/lingdong.2.31.png, transparency 0.5
*   Blush:      makeup/blush/luori.2.31.png, transparency 0.8
*   Eyeliner:   makeup/eyeliner_292929/qizhi.2.31.png, transparency 0.5
*   Lipstick:   makeup/mouth_yaochun/nanguase.2.31.png, transparency 0.5
*   Highlight:  makeup/highlight/highlight.2.12.png, transparency 0.4
*
* 4. Nightclub makeup:
*   Eye shadow: makeup/eyeshadow/yeqiangwei.2.31.png, transparency 0.7
*   Eyelashes:  makeup/eyelash/zhixing.2.31.png, transparency 0.5
*   Blush:      makeup/blush/shaonv.2.31.png, transparency 0.8
*   Eyeliner:   makeup/eyeliner_292929/wenrou.2.31.png, transparency 0.5
*   Lipstick:   makeup/mouth_zirun/zhenggongse.2.31.png, transparency 0.5
*   Highlight:  makeup/highlight/highlight.2.12.png, transparency 0.4
**/

// Set the material transparency.
// Parameter 2: transparency of the material.
// Parameter 3: reserved.
engine.setMakeupAlpha(MakeupType.kMakeupBlush, 0.6f, 0.3f);

Disable makeup.

engine.setMakeupImage(MakeupType.kMakeupBlush, new String[], BlendType.kBlendNormal, 15);

Enable the aegyo-sal effect.

// Enable the aegyo-sal effect.
// Parameter 2: enable (true/false). Parameter 3: enable debugging (true/false).
engine.enableBeautyType(BeautyFilterType.kMakeup, true, false);

// Only built-in materials are used for the aegyo-sal effect.
engine.setMakeupImage(MakeupType.kMakeupWocan,
                      new String[]{""},
                      BlendType.kBlendCurve, 15);

engine.setMakeupAlpha(MakeupType.kMakeupWocan, 0.6f, 0.3f);

Disable the aegyo-sal effect.

engine.setMakeupImage(MakeupType.kMakeupWocan, new String[], BlendType.kBlendCurve, 15);

Hair color

engine.enableBeautyType(BeautyFilterType.kHairColor, true);
/**
 * Hair colors are expressed as red, green, and blue (RGB) floating-point values.
 * Sample colors:
 *   Blue:     [0.3137f, 0.3137f, 0.6275f]
 *   Purple:   [0.6078f, 0.3529f, 0.6275f]
 *   Sky blue: [0.3333f, 0.5492f, 0.5491f]
 *   Yellow:   [0.6471f, 0.5294f, 0.3529f]
 *   Green:    [0.3725f, 0.5882f, 0.3137f]
 *   Brown:    [0.3922f, 0.3333f, 0.3137f]
 *   Red:      [0.5098f, 0.2745f, 0.2745f]
 */
engine.setHairColor(
  getQueenParam().hairRecord.colorRed,
  getQueenParam().hairRecord.colorGreen,
  getQueenParam().hairRecord.colorBlue);

Filters

// Enable filters.
engine.enableBeautyType(BeautyFilterType.kLUT, true);
// Set the filter. Use a path relative to the assets folder (for example, /lookups/lookup_1.png)
// or an absolute path.
engine.setFilter(lutResPath); 
// Set the filter intensity. Valid values: 0 to 1.
engine.setBeautyParam(BeautyParams.kBPLUT, 1.0f); 

Stickers

// Remove the sticker at the specified path.
engine.removeMaterial(oldStickerResPath);
// Add a sticker. Each sticker can only be added once.
// Use a path relative to the assets folder (for example, /sticker/baiyang) or an absolute path.
engine.addMaterial(stickerResPath);

Chroma key

/**
 * Configure chroma key.
 * @param backgroundPath Path of the replacement background image. Pass "" to disable chroma key.
 * @param blueScreenEnabled true: use blue screen; false: use green screen.
 * @param threshold Valid values: 20 to 60. Default: 30.
 */
engine.setGreenScreen(String backgroundPath, boolean blueScreenEnabled, float threshold);

Background replacement

// Set the performance mode before enabling background replacement.
// Supported modes: Auto Mode, Best Quality Mode, Balance Mode, and Best Performance Mode.
// Default: Auto Mode.
engine.setSegmentPerformanceMode(SegmentPerformanceMode.Auto);
// Remove the background at the specified path.
engine.removeMaterial(oldBackgroundResPath);
// Add a background image. Each image can only be added once.
// Use a path relative to the assets folder (for example, /static/xiaomanyao) or an absolute path.
engine.addMaterial(backgroundResPath);
// Enable background bokeh (background blur) instead of background replacement.
engine.enableBeautyType(BeautyFilterType.kBTBackgroundProcess, true);
// By default, bokeh blurs the background. To use a transparent background instead
// (for foreground compositing), set the background process type as follows.
engine.setSegmentBackgroundProcessType(BackgroundProcessType.kBackgroundTransparent);

AR writing

/**
 * Enable augmented reality (AR) writing.
 * Parameter 1: enable (true/false).
 * Parameter 2: mode — 1 for writing mode, 2 for drawing mode.
 */
engine.setArWriting(true, getQueenParam().sArWritingRecord.mode);

Intelligent dynamic optimization

// Enable intelligent dynamic optimization.
engine.enableBeautyType(BeautyFilterType.kBTAutoFilter, true);
// Disable intelligent dynamic optimization.
engine.enableBeautyType(BeautyFilterType.kBTAutoFilter, false);

Gesture recognition

Register and deregister the algorithm callback.

/** Register the algorithm callback. **/
// Create an algorithm instance from the QueenEngine handle.
// The algorithm runs as soon as the callback is registered.
// Parameter 3: algorithm type. See the AlgType class for all supported types.
// The following example registers a gesture recognition algorithm.
Algorithm algorithm = new Algorithm(engine.getEngineHandler(), "", com.taobao.android.libqueen.models.AlgType.kAAiGestureDetect);
algorithm.registerAlgCallBack(new Algorithm.OnAlgDetectListener() {
  @Override
  public int onAlgDetectFinish(int algId, Object algResult) {
    if (algResult instanceof com.taobao.android.libqueen.algorithm.GestureData) {
      // GestureData contains both static and dynamic gesture data.
      com.taobao.android.libqueen.algorithm.GestureData gestureData = (com.taobao.android.libqueen.algorithm.GestureData) algResult;
    }
    return 0;
  }
});

/** Deregister the algorithm callback. **/
// If the associated QueenEngine instance is still alive, deregister the callback manually.
// If QueenEngine is destroyed, the algorithm instance is automatically invalidated.
algorithm.unRegisterAlgCallBack();

Movement detection

Register and deregister the algorithm callback.

/** Register the algorithm callback. **/
// Create an algorithm instance from the QueenEngine handle.
// The algorithm runs as soon as the callback is registered.
// Parameter 3: algorithm type. See the AlgType class for all supported types.
// The following example registers a movement detection algorithm.
Algorithm algorithm = new Algorithm(engine.getEngineHandler(), "", com.taobao.android.libqueen.models.AlgType.kQueenAIBodySportDetect);
algorithm.registerAlgCallBack(new Algorithm.OnAlgDetectListener() {
  @Override
  public int onAlgDetectFinish(int algId, Object algResult) {
    if (algResult instanceof BodyDetectData) {
          BodyDetectData resultData = (BodyDetectData)algResult;
          int sportType = resultData.getBodySportType();
          if (sportType <= 0) {
            // Handle posture recognition.
            int poseType = resultData.getBodyPoseType();
            sb.append("[Posture recognition]:").append(getBodyPoseName(poseType));
          } else {
            // Count the number of repetitions for the detected movement.
            int sportCount = resultData.getBodySportCount();
            sb.append("[Movement]:").append(getBodySportPoseName(sportType)).append("\r\n")
              .append("[Count]:").append(sportCount);
          }
        }
    return 0;
  }
});

/** Deregister the algorithm callback. **/
// If the associated QueenEngine instance is still alive, deregister the callback manually.
// If QueenEngine is destroyed, the algorithm instance is automatically invalidated.
algorithm.unRegisterAlgCallBack();