Developing for SnapKit on Android: Creative Kit SDK for Snapchat

Snapchat announced their developer SDK in mid-June of this year and has released their documentation here. While it is clear that they are making a robust, useful API for developers to link to new or already existing apps, their documentation is still in the very early stages of development.

As such, there are no sample apps currently in their documentation or on GitHub (at least none when I started writing this article). Since I already integrated the Snap Kit SDK for my job at Poshmark, I thought I would help by writing an instructional article on integrating Snap Kit (the Creative Kit) into a small app and also posting the sample code on GitHub.

This may seem lengthy but I wanted to make sure I covered the entirety of integrating basic Snapchat photo content send call into an app with an image picker including signing up for a Snap Kit client ID.


Setting up on the Snap Kit developer portal

First things first: get a client ID from the Snap Kit developer portal.

Important: You will need a Snapchat account to register for the Snap Kit developer portal.

Create a Snapchat account ( I strongly advise against using your personal account for testing/development especially if you are doing this for your company) and agree to the Developer Terms of Service.

In the dashboard, click the big “+” button and create your app.

After you hit “continue”, you will be taken to your app’s dashboard.

In order to make use of the client IDs that you are given for your app, you will need to put in the package name of the app you are building, using your “dev” or testing build package name for the Development app package name.

If you do not know how to find your app package name, check out Google’s documentation here.


Now that you have a Snap Kit client ID, it is time to start building the application.

For the sake of this simplified exercise, I have created a small sample app called “SnapKitTestApp” using the standard Android Studio flow and an empty Activity.

Importing Snapchat [and other libraries]

Put the following in the Project level build.gradle file in the “allprojects” section inside of “repositories”:

maven {
url "https://storage.googleapis.com/snap-kit-build/maven"
}

Put the following in the module level build.gradle file in the dependencies section:

implementation([
'com.snapchat.kit.sdk:creative:1.1.3',
'com.snapchat.kit.sdk:core:1.1.3'
])

[Version numbers may change, check latest documentation for latest version]

This is also when we will implement the image picker library [I will be using EasyImage from jkwiecien] and a permissions library [I will be using EasyPermissions from Google Samples]. There’s no point in reinventing the wheel for this short project.

Put the following in the Project level build.gradle file in the “allprojects” section inside of “repositories”:

maven { url 'https://jitpack.io' }

Put the following in the module level build.gradle file in the dependencies section:

implementation 'com.github.jkwiecien:EasyImage:2.1.0'
implementation 'pub.devrel:easypermissions:1.2.0'

Add the following inside the <application> tag in the Android Manifest file below the Main Activity:

<provider            android:authorities="${applicationId}.fileprovider"            android:name="android.support.v4.content.FileProvider"            android:exported="false"            android:grantUriPermissions="true">            
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" /> </provider>

After the <provider>, add the Snapchat Kit app id as so:

<meta-data android:name="com.snapchat.kit.sdk.clientId" android:value="your-client-id-here" />

Now, sync your gradle files and we will construct the simple UI for this app.


UI

I’m not going to spend much time on the UI since this is just a sample app for demonstrating how to use an SDK to link to an external app. There is just a button for starting the send snap process and a text view.

Linking everything up

Now we go to the MainActivity to link the Button, the image picker and the SnapKit API.
First, initialize the button and assign a click listener in onCreate(). We also set up the EasyImage picker.

EasyImage.configuration(this)
.setAllowMultiplePickInGallery(false);
Button sendButton = findViewById(R.id.sendPhotoButton);
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startPhotoSend();
}
});

startPhotoSend() checks for permissions. If the app has the permission to write to storage, it opens the PhotoPicker. Otherwise, it asks for Permission then the user can retry.

private void startPhotoSend() {
String[] perms = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
if(EasyPermissions.hasPermissions(this, perms)) {
//has permissions
EasyImage.openGallery(MainActivity.this, 0);
photoPicker = true;
} else {
//does not have permissions
EasyPermissions.requestPermissions(this, getString(R.string.app_permission_text), WRITE_STORAGE_PERM, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);

// Forward results to EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}

When the photo is picked (note we disabled multiple pick in gallery in the set up of the EasyImage), we handle the result in onActivityResult().

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(photoPicker) {
EasyImage.handleActivityResult(requestCode, resultCode, data, this, new DefaultCallback() {
@Override
public void onImagePickerError(Exception e, EasyImage.ImageSource source, int type) {
photoPicker = false;
//Some error handling
}

@Override
public void onImagesPicked(List<File> imagesFiles, EasyImage.ImageSource source, int type) {
//Handle the images
photoPicker = false;
onPhotosReturned(imagesFiles);
}
});
}
}

Now we must set up SnapCreativeKitAPI. Inside onCreate() again:

snapCreativeKitApi = SnapCreative.getApi(this);

Then we create the onPhotosReturned(List<File> imageFiles) method. Note that the SnapCreativeKitAPI creates SnapPhotoFiles from File objects.

private void onPhotosReturned(List<File> imageFiles) {
Log.d("photo Returned", "Photo returned");
SnapMediaFactory snapMediaFactory = SnapCreative.getMediaFactory(this);
if(imageFiles.size() == 1) {
SnapPhotoFile photoFile;
try {
photoFile = snapMediaFactory.getSnapPhotoFromFile(imageFiles.get(0));
} catch (SnapMediaSizeException e) {
e.printStackTrace();
return;
}
SnapPhotoContent snapPhotoContent = new SnapPhotoContent(photoFile);
snapPhotoContent.setCaptionText("Sent from My Android App");
snapPhotoContent.setAttachmentUrl("www.google.com");

snapCreativeKitApi.send(snapPhotoContent);
Log.d("Snapchat", "Photo sent to snapchat");
}
}

Let’s break it down bit by bit.

SnapMediaFactory snapMediaFactory = SnapCreative.getMediaFactory(this);

Here we create our SnapMediaFactory which we use to create the SnapPhotoFile from the File image we get from the gallery picker.

SnapPhotoFile photoFile;
try {
photoFile = snapMediaFactory.getSnapPhotoFromFile(imageFiles.get(0));
} catch (SnapMediaSizeException e) {
e.printStackTrace();
return;
}
SnapPhotoContent snapPhotoContent = new SnapPhotoContent(photoFile);

We need to put the getSnapPhotoFromFile() inside of a try-catch in order to prevent SnapMediaSizeExceptions being thrown. We then create a SnapPhotoContent to store the photo file and the content that will go with the photo (Sticker, caption and attachment urls).

snapPhotoContent.setCaptionText("Sent from My Android App");
snapPhotoContent.setAttachmentUrl("www.google.com");

snapCreativeKitApi.send(snapPhotoContent);

Finally we tell the snapCreativeKitApi to send the snapPhotoContent.

There you have it! You have integrated a fairly simple SnapPhoto sender using the SnapChat Creative Kit!

Full source code available here. Feel free to reach out if you have any issues.