Androidアプリを作成したときに、他のアプリからファイルの共有を受け取ることができます。
しかしながら、共有のためのIntentに含まれるflagsの内容によっては、受け取った瞬間にアプリが再起動してしまう場合があります。
アプリ内の状態を保持したまま受け取りたい場合には不便です。それを回避するためのCordovaプラグインを作成しました。
そのために、共有を受け取る専用のアクティビティを用意します。専用アクティビティで受信した後、本来受け取りたかったアクティビティにIntentを転送します。
そのとき、flagsは、差しさわりのない値(FLAG_ACTIVITY_SINGLE_TOP | FLAG_GRANT_READ_URI_PERMISSION)にすることで、専用アクティビティは再起動されてしまいますが、転送を受け取った側のアクティビティは再起動することがなくなります。
package jp.or.sample.ContentUrlPlugin;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.content.ComponentName;
public class IntentReceiverActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent original = getIntent();
// Intent safeIntent = new Intent(this, MainActivity.class);
String packageName = getApplicationContext().getPackageName();
Intent safeIntent = new Intent();
safeIntent.setComponent(new ComponentName(packageName, packageName + ".MainActivity"));
safeIntent.setAction(Intent.ACTION_SEND);
safeIntent.setData(original.getData());
safeIntent.setType(original.getType());
safeIntent.putExtras(original.getExtras());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
safeIntent.setClipData(original.getClipData());
}
safeIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(safeIntent);
finish();
}
}
必要に応じて、転送したいActivityのクラスを変更してください。
<activity
android:name="jp.or.sample.ContentUrlPlugin.IntentReceiverActivity"
android:exported="true"
android:launchMode="standard"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
必要に応じて、受け取りたいmimeTypeを変えてください。
Cordovaでの利用方法
扱いやすいようにCordovaプラグインを作成しておきました。
内部で、以下のIntentを扱うCordovaプラグインを使います。
あとは、Javascriptで以下のように記述すると、アクティビティが再起動することなくIntentを受け取れます。
window.plugins.intent.getCordovaIntent(async (intent) => {
console.log("getCordovaIntent", intent);
}, function () {});
window.plugins.intent.setNewIntentHandler(async (intent) => {
console.log("setNewIntentHandler", intent);
});
また、取得されるIntentの中に、content:// で始まるファイルのURLが取得されますが、ここからファイルの内容を取得する関数も用意しておきました。
var content = await contenturl.readContent(intent.clipItems[0].uri);
Cordovaサンプルアプリ
このプラグインを利用したサンプルアプリを用意しました。
他のアプリから共有を受け取るアプリです。
また、BLEペリフェラルとしても動作でき、他のWeb Bluetooth APIに対応したブラウザから、小さなテキストやファイルを送受信できるようにしました。
> cd Cordova/BleDataShareClient
> cordova plugin add github:poruruba/cordova-plugin-contenturl
> cordova plugin add github:napolitano/cordova-plugin-intent
> cordova platform add android
> cordova build android
> cordova run android
vConsoleが邪魔な場合は、const vConsole = new VConsole();の部分をコメントアウトしてください。
ブラウザ側は、以下のURLを開いてください。
以上

