Showcases how to build a custom share menu action.


/*
* Copyright © 2014-2026 PSPDFKit GmbH. All rights reserved.
*
* The PSPDFKit Sample applications are licensed with a modified BSD license.
* Please see License for details. This notice may not be removed from this file.
*/
package com.pspdfkit.catalog.examples.java;
import static com.pspdfkit.catalog.tasks.ExtractAssetTask.extract;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ShareCompat;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.pspdfkit.catalog.R;
import com.pspdfkit.catalog.SdkExample;
import com.pspdfkit.configuration.activity.PdfActivityConfiguration;
import com.pspdfkit.document.processor.PdfProcessorTask;
import com.pspdfkit.document.sharing.DefaultDocumentSharingController;
import com.pspdfkit.document.sharing.DocumentSharingIntentHelper;
import com.pspdfkit.document.sharing.DocumentSharingManager;
import com.pspdfkit.document.sharing.ShareTarget;
import com.pspdfkit.document.sharing.SharingOptions;
import com.pspdfkit.ui.PdfActivity;
import com.pspdfkit.ui.PdfActivityIntentBuilder;
import com.pspdfkit.ui.actionmenu.ActionMenu;
import com.pspdfkit.ui.actionmenu.ActionMenuItem;
import com.pspdfkit.ui.actionmenu.ActionMenuListener;
import com.pspdfkit.ui.actionmenu.FixedActionMenuItem;
import com.pspdfkit.ui.actionmenu.SharingMenu;
import com.pspdfkit.ui.actionmenu.SimpleActionMenuListener;
import java.util.Collections;
public class CustomSharingMenuExample extends SdkExample {
public CustomSharingMenuExample(Context context) {
super(context, R.string.documentSharingMenuExampleTitle, R.string.documentSharingMenuExampleDescription);
}
@Override
public void launchExample(
@NonNull final Context context, @NonNull final PdfActivityConfiguration.Builder configuration) {
// This example uses a custom activity which shows how to implement custom sharing.
// For sake of simplicity, deactivate actions.
configuration
.annotationListEnabled(false)
.searchEnabled(false)
.outlineEnabled(false)
.thumbnailGridEnabled(false);
// First extract the document from the assets.
extract(ANNOTATIONS_EXAMPLE, getTitle(), context, documentFile -> {
// To start CustomSharingMenuActivity create a launch intent using this builder.
final Intent intent = PdfActivityIntentBuilder.fromUri(context, Uri.fromFile(documentFile))
.configuration(configuration.build())
.activityClass(CustomSharingMenuActivity.class)
.build();
// Start the CustomSharingMenuActivity for the extracted document.
context.startActivity(intent);
});
}
/**
* This activity showcases how to add custom sharing action to sharing menu displayed in a {@link
* BottomSheetDialog}.
*/
public static class CustomSharingMenuActivity extends PdfActivity implements ActionMenuListener {
private static final String STATE_SHOWING_MAIL_TO_SHARING_MENU = "STATE_SHOWING_MAIL_TO_SHARING_MENU";
@Nullable
private SharingMenu mailToActionMenu;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set listener for sharing menu.
setSharingActionMenuListener(this);
// Restore "Mail to" sharing menu if shown before orientation change.
if (savedInstanceState != null) {
if (savedInstanceState.getBoolean(STATE_SHOWING_MAIL_TO_SHARING_MENU, false)) {
showMailToSharingMenu();
}
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_SHOWING_MAIL_TO_SHARING_MENU, mailToActionMenu != null);
}
/** Override onPrepareActionMenu(ActionMenu) to modify sharing menu contents. */
@Override
public boolean onPrepareActionMenu(@NonNull ActionMenu actionMenu) {
// Add fixed menu item to action menu.
actionMenu.addMenuItem(
new FixedActionMenuItem(this, R.id.item_send_mail, R.drawable.ic_custom_sharing, R.string.mail));
// Make sure to return true, if you want sharing menu to display your actions.
return true;
}
@Override
public void onDisplayActionMenu(@NonNull ActionMenu actionMenu) {}
@Override
public void onRemoveActionMenu(@NonNull ActionMenu actionMenu) {}
@Override
public boolean onActionMenuItemClicked(@NonNull ActionMenu actionMenu, @NonNull ActionMenuItem menuItem) {
if (menuItem.getItemId() == R.id.item_send_mail) {
actionMenu.dismiss();
// Show new sharing menu with "Mail to" action.
showMailToSharingMenu();
return true;
}
return false;
}
/** Override to handle click events for your custom sharing menu items. */
@Override
public boolean onActionMenuItemLongClicked(
@NonNull ActionMenu actionMenu, @NonNull ActionMenuItem clickedItem) {
return false;
}
private void showMailToSharingMenu() {
mailToActionMenu = new SharingMenu(this, shareTarget -> {
// Start sharing flow.
DocumentSharingManager.shareDocument(
new MailToDocumentSharingController(CustomSharingMenuActivity.this, shareTarget),
getDocument(),
new SharingOptions(PdfProcessorTask.AnnotationProcessingMode.FLATTEN));
});
// Register listener for action menu to get notified when menu is hidden.
mailToActionMenu.addActionMenuListener(new SimpleActionMenuListener() {
@Override
public void onRemoveActionMenu(@NonNull ActionMenu actionMenu) {
mailToActionMenu = null;
}
});
// Set menu title.
mailToActionMenu.setTitle(R.string.mail_to);
// Make sharing menu show apps that handle mail to action.
mailToActionMenu.setShareIntents(Collections.singletonList(getMailToIntent(Uri.EMPTY)));
// Show dialog.
mailToActionMenu.show();
}
@NonNull
private Intent getMailToIntent(@NonNull Uri shareUri) {
Intent mailToIntent = ShareCompat.IntentBuilder.from(CustomSharingMenuActivity.this)
// Use "application/pdf" as mime type.
.setType(DocumentSharingIntentHelper.MIME_TYPE_PDF)
// Add shared document uri as data stream.
.addStream(shareUri)
// Optionally specify initial email data - to, cc, subject, body text etc.
.addEmailTo("mail@to.com")
.setSubject("Subject")
.setText("I'm email body.")
// Build share intent.
.getIntent();
// Target email apps by changing the Intent action to SENDTO and
// by limiting the Intent to apps that can handle mailto:// URIs.
mailToIntent.setAction(Intent.ACTION_SENDTO);
mailToIntent.setData(Uri.parse("mailto:"));
return mailToIntent;
}
/**
* Example implementation of a custom share controller that shares document to single {@link
* ShareTarget}.
*/
private class MailToDocumentSharingController extends DefaultDocumentSharingController {
public MailToDocumentSharingController(@NonNull Context context, @NonNull ShareTarget shareTarget) {
super(context, shareTarget);
}
@Override
public void onDocumentPrepared(@NonNull Uri shareUri) {
// Guard for null context. This can happen when sharing controller is detached
// from it's owning activity (for example while changing orientation).
if (getContext() == null) return;
// Build share intent.
final Intent shareIntent = getMailToIntent(shareUri);
if (getShareTarget() != null) {
// Set package to share target package.
shareIntent.setPackage(getShareTarget().getPackageName());
// Finally start share intent.
getContext().startActivity(shareIntent);
}
}
}
}
}

This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.