Developer Documentation: How to create Quik edits from your app (Quik API)

Android Apps

Create a Quik project

The Quik app responds to any intent on the package `com.stupeflix.replay` following this spec:

    <action android:name="android.intent.action.SEND"/>
    <action android:name="android.intent.action.SEND_MULTIPLE"/>

    <category android:name="android.intent.category.DEFAULT"/>

    <data android:mimeType="image/*"/>
    <data android:mimeType="video/*"/>


Collections of media must be in the `ClipData` attached to the intent (for preserving permissions), this is very important.

The sender app can force the intent to target the Quik app like below:

Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);

// "clipData" contains all your URIs
intent.setType("image/*, video/*");

// Set read permissions flag for us to resolve (via ContentProvider)
// any ContentUri attached to the intent.
// (be it a file on sender's internal storage).

if (intent.resolveActivity(getPackageManager()) != null) {
  // Quik app is installed and can handle the feature

Quik can handle any type of local URI, `content://` `file://` or plain path.  Quik requests external storage permissions in the process if it doesn't have it already.

`content://` URI can resolve on the private storage of your app, you just need to attach a read permissions to the intent like showed above so we can access it through your ContentProvider.

Quik 1.4 and up: Configurable project

In Quik 1.4, we added support for configurable project. 
In "external" project mode, Quik will also result an unique project ID that you can re-use to re-open an "external" project later.

    public void startQuik() {

	Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);

        // Force intent to target Quik app.
        intent.setType("image/*, video/*");

        // "clipData" contains all your assets URIs. (max count: 75).
        // Can be null if project_id is present then Quik will 
	// use assets from project.

        /* Intent optional arguments */

	// enable_external_project
        // -    true: enable external mode for this project, 
	//	Quik will result a project id to your activity.
        // -    false: classic behaviour, keep project internal to Quik
        intent.putExtra("enable_external_project", true);

        // project_id, the unique Quik identifier for an external project.
        // -    null: Quik create a new project with a new id.
        // -    project id: restore a previous project in Quik
	// project ID must come from the Quik result, in your onActivityResult
        // intent.putExtra("project_id", "<id>");

        // add_assets (default true)
        // -    true: Add ClipData's assets at the end of project
        // -    false: Clear assets from existing project before adding ClipData's assets
        // Ignored if project_id is null
        intent.putExtra("add_assets", true);

        // Set title for a project.
        // If present, Quik does not show a Title dialog for a new project
        intent.putExtra("project_title", "This is a title");

        // enable_upload (default true)
        // -    false: Disable video upload 
	// (i.e. remove "share link" action during video save)
        intent.putExtra("enable_upload", false);

        // branding_off, available only on new project (default to user preference)
        // -    true: Remove the official Quik Outro from the project timeline
        // -    false: Add the Quik Outro in the timeline
        intent.putExtra("branding_off", true);

        // aspect_ratio, available only on new project (default to user preference)
        // -    "square": aspect ratio 1/1
        // -    "large": aspect ratio 16/9
        intent.putExtra("aspect_ratio", "square");

        // Suggested duration in seconds for a new project (default best Quik duration).
        intent.putExtra("project_duration", 10);

	// Set a style, available styles are (same order as the app shows):
	// grammy,gopro,lumiere,lapse,slice,overlay,
	// blocky,simple,sport,glide,kinetic,swift,
	// palette,doisneau,donotblink,bold,diamond,split,
	// picnic,origami,lightpanes,bouncy,seasons_summer,
	// seasons_autumn,seasons_winter,seasons_spring
	// Available since Quik 1.4.1
	intent.putExtra("style", "gopro");

	// Use a random style
	intent.putExtra("random_style", true);

        // Where we should save the project video file. (default in DCIM/Quik/)

        // Set read permissions flag for us to resolve any ContentUri attached to 
	// the intent that resolve on your internal storage.
        // (via ContentProvider)

        if (intent.resolveActivity(getPackageManager()) != null) {
            // Quik app is installed and can respond to the intent
	    // See below for possible results
            startActivityForResult(intent, 42);


    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == 42) {
            if (resultCode == RESULT_OK) {
                // Identifier of a project.
                // Pass this id to the intent to re-open a previous Quik project.
                String projectId = intent.getStringExtra("project_id");

                // file video path
                // -    null if the user didn't save his project into a file yet
                // -    or absolute video file path of the saved file from a project
                String videoFilePath = intent.getStringExtra("video_file_path");

                // project URI in our provider (read only)
                Uri projectUri = intent.getData();

            } else if (resultCode == RESULT_CANCELED) {
                if (intent != null) {
                    int errorCode = intent.getIntExtra("error_code", -1);
	            // Possible error code :
            	    // - 400 : ClipData is empty or null
                    // - 403 : Your app doesn't have the permission to open the project.

Quik 1.6 and up: Play a Quik project video

Intent intent = new Intent(Intent.ACTION_VIEW);

// Play project video with id = 1
Uri projectUri = Uri.parse("content://com.stupeflix.replay.provider/projects/1");

if (intent.resolveActivity(getPackageManager()) != null) {
	startActivityForResult(intent, 43); 
// result error_code = 400 if project does not exist