コンテンツへスキップ

共有ターゲットの使用を開始する

このガイドでは、Capacitor Share Target プラグインを統合して、アプリが他のアプリケーションから共有コンテンツを受信できるようにする手順を説明します。

npm を使用してプラグインをインストールします。

Terminal window
npm install @capgo/capacitor-share-target
npx cap sync

<activity> タグ内の AndroidManifest.xml にインテント フィルターを追加します。

テキストコンテンツを受け入れる

Section titled “テキストコンテンツを受け入れる”
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>

すべてのコンテンツ タイプを受け入れる

Section titled “すべてのコンテンツ タイプを受け入れる”
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>

iOS の場合、共有拡張機能を作成する必要があります。

1. Xcode で共有拡張機能を作成します

Section titled “1. Xcode で共有拡張機能を作成します”
  1. Xcode でプロジェクトを開きます
  2. [ファイル] > [新規] > [ターゲット] に移動します。
  3. [拡張機能の共有] を選択し、[次へ] をクリックします。
  4. 名前を付けて (例: 「ShareExtension」)、完了 をクリックします。
  5. プロンプトが表示されたら、スキームをアクティブ化します
  1. メインのアプリターゲットで、署名と機能に移動します。
  2. [+ 機能] をクリックし、アプリ グループ を追加します。
  3. アプリ グループを作成または選択します (例: group.com.yourcompany.yourapp)
  4. 共有拡張ターゲットに対して繰り返します。

共有拡張機能は、メイン アプリがアクセスできるように、共有データをアプリ グループ コンテナーに保存する必要があります。

iOS セットアップの詳細については、Apple の共有拡張機能のドキュメント を参照してください。

import { CapacitorShareTarget } from '@capgo/capacitor-share-target';
CapacitorShareTarget.addListener('shareReceived', (event) => {
console.log('Received share event');
console.log('Title:', event.title);
console.log('Texts:', event.texts);
// Handle shared files
if (event.files && event.files.length > 0) {
event.files.forEach(file => {
console.log(`File: ${file.name}`);
console.log(`Type: ${file.mimeType}`);
console.log(`URI: ${file.uri}`);
});
}
});

以下は、さまざまな種類の共有コンテンツを処理する包括的な例です。

import { CapacitorShareTarget } from '@capgo/capacitor-share-target';
class ShareTargetService {
private listener: any;
initialize() {
this.listener = CapacitorShareTarget.addListener('shareReceived', (event) => {
this.handleSharedContent(event);
});
console.log('Share target listener initialized');
}
handleSharedContent(event: any) {
console.log('=== Share Received ===');
// Handle title
if (event.title) {
console.log('Title:', event.title);
this.showNotification('Shared: ' + event.title);
}
// Handle text content
if (event.texts && event.texts.length > 0) {
event.texts.forEach((text: string, index: number) => {
console.log(`Text ${index + 1}:`, text);
this.processSharedText(text);
});
}
// Handle files
if (event.files && event.files.length > 0) {
console.log(`Received ${event.files.length} file(s)`);
event.files.forEach((file: any) => {
console.log('File details:');
console.log(' Name:', file.name);
console.log(' Type:', file.mimeType);
console.log(' URI:', file.uri);
this.processSharedFile(file);
});
}
}
processSharedText(text: string) {
// Check if it's a URL
if (this.isURL(text)) {
console.log('Shared URL detected:', text);
// Handle URL (e.g., create bookmark)
this.saveBookmark(text);
} else {
console.log('Shared text detected');
// Handle plain text (e.g., create note)
this.createNote(text);
}
}
processSharedFile(file: any) {
const fileType = file.mimeType.split('/')[0];
switch (fileType) {
case 'image':
console.log('Processing shared image');
this.handleImage(file);
break;
case 'video':
console.log('Processing shared video');
this.handleVideo(file);
break;
case 'audio':
console.log('Processing shared audio');
this.handleAudio(file);
break;
case 'application':
console.log('Processing shared document');
this.handleDocument(file);
break;
default:
console.log('Processing generic file');
this.handleGenericFile(file);
}
}
handleImage(file: any) {
// Process image file
console.log('Saving image:', file.name);
// Implementation: Save to gallery, upload, etc.
}
handleVideo(file: any) {
// Process video file
console.log('Saving video:', file.name);
}
handleAudio(file: any) {
// Process audio file
console.log('Saving audio:', file.name);
}
handleDocument(file: any) {
// Process document file
console.log('Saving document:', file.name);
}
handleGenericFile(file: any) {
// Process generic file
console.log('Saving file:', file.name);
}
isURL(text: string): boolean {
try {
new URL(text);
return true;
} catch {
return false;
}
}
saveBookmark(url: string) {
console.log('Creating bookmark for:', url);
// Implementation
}
createNote(text: string) {
console.log('Creating note with text:', text.substring(0, 50));
// Implementation
}
showNotification(message: string) {
console.log('Notification:', message);
// Show toast or notification
}
cleanup() {
if (this.listener) {
this.listener.remove();
}
}
}
// Usage
const shareTarget = new ShareTargetService();
shareTarget.initialize();
// Cleanup when app closes
// shareTarget.cleanup();
import { useEffect } from 'react';
import { CapacitorShareTarget } from '@capgo/capacitor-share-target';
function useShareTarget(onShareReceived: (event: any) => void) {
useEffect(() => {
const listener = CapacitorShareTarget.addListener('shareReceived', onShareReceived);
return () => {
listener.remove();
};
}, [onShareReceived]);
}
// Usage in component
function App() {
useShareTarget((event) => {
console.log('Share received:', event);
// Handle shared content
});
return <div>Your App</div>;
}
import { onMounted, onUnmounted } from 'vue';
import { CapacitorShareTarget } from '@capgo/capacitor-share-target';
export default {
setup() {
let listener: any;
onMounted(() => {
listener = CapacitorShareTarget.addListener('shareReceived', (event) => {
console.log('Share received:', event);
// Handle shared content
});
});
onUnmounted(() => {
if (listener) {
listener.remove();
}
});
}
};

さまざまなコンテンツタイプの処理

Section titled “さまざまなコンテンツタイプの処理”
if (event.texts && event.texts.length > 0) {
const text = event.texts[0];
if (text.startsWith('http://') || text.startsWith('https://')) {
// Handle URL
window.open(text, '_blank');
}
}
if (event.files) {
const images = event.files.filter(f => f.mimeType.startsWith('image/'));
images.forEach(async (image) => {
// Read and display image
const response = await fetch(image.uri);
const blob = await response.blob();
const imageUrl = URL.createObjectURL(blob);
// Display or process image
console.log('Image URL:', imageUrl);
});
}
if (event.files && event.files.length > 1) {
console.log(`Processing ${event.files.length} files`);
const processPromises = event.files.map(file =>
processFile(file)
);
await Promise.all(processPromises);
console.log('All files processed');
}
  1. 複数のコンテンツ タイプの処理: テキスト、URL、およびファイルを受信できるように準備します。
  2. コンテンツの検証: 処理する前に MIME タイプを確認します。
  3. フィードバックの提供: 受け取った内容をユーザーに表示します
  4. 処理エラー: ファイル URI が無効であるかアクセスできない可能性があります
  5. リスナーのクリーンアップ: 不要な場合はリスナーを削除します
  6. 徹底的にテストします: さまざまなアプリやコンテンツ タイプでテストします
  7. アクセス許可のリクエスト: 一部のファイルの種類では追加のアクセス許可が必要な場合があります

android.intent.action.MAIN を持つ <activity> タグ内の AndroidManifest.xml でインテント フィルターが正しく設定されていることを確認します。

iOS 共有拡張機能が表示されません

Section titled “iOS 共有拡張機能が表示されません”
  1. 両方のターゲットでアプリ グループが構成されていることを確認します
  2. 共有拡張機能が有効になっていることを確認します
  3. 共有拡張機能の Info.plist が正しい構成になっていることを確認します
try {
const response = await fetch(file.uri);
const blob = await response.blob();
// Process blob
} catch (error) {
console.error('Failed to access file:', error);
// Show error to user
}