0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Androidで共有を受け取ったときにタスクを再起動されないようにする

Last updated at Posted at 2025-11-09

Androidアプリを作成したときに、他のアプリからファイルの共有を受け取ることができます。
しかしながら、共有のためのIntentに含まれるflagsの内容によっては、受け取った瞬間にアプリが再起動してしまう場合があります。
アプリ内の状態を保持したまま受け取りたい場合には不便です。それを回避するためのCordovaプラグインを作成しました。

そのために、共有を受け取る専用のアクティビティを用意します。専用アクティビティで受信した後、本来受け取りたかったアクティビティにIntentを転送します。
そのとき、flagsは、差しさわりのない値(FLAG_ACTIVITY_SINGLE_TOP | FLAG_GRANT_READ_URI_PERMISSION)にすることで、専用アクティビティは再起動されてしまいますが、転送を受け取った側のアクティビティは再起動することがなくなります。

IntentReceiverActivity.java
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のクラスを変更してください。

AndroidManifest.xml
            <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を受け取れます。

start.js
                window.plugins.intent.getCordovaIntent(async (intent) => {
                    console.log("getCordovaIntent", intent);
                }, function () {});
                window.plugins.intent.setNewIntentHandler(async (intent) => {
                    console.log("setNewIntentHandler", intent);
                });

また、取得されるIntentの中に、content:// で始まるファイルのURLが取得されますが、ここからファイルの内容を取得する関数も用意しておきました。

js/start.js
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

image.png

vConsoleが邪魔な場合は、const vConsole = new VConsole();の部分をコメントアウトしてください。

ブラウザ側は、以下のURLを開いてください。

image.png

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?