この記事はAndroidスマホ用のアプリ開発の中で、
今後の開発で再使用性が高いと思われるコーディングをまとめたものです。
Javaの開発経験、XML構文規則、Androidのアプリ開発経験がある方を対象としています。
Androidのアプリ開発でお役にたててれば、嬉しいです。
(これからAndroidのアプリ開発やJavaでの開発を始めたい方への案内は、記事の最後で紹介します)
ファイルを起動引数として、別アプリ(サービス)を起動する
HERO12以降は熱暴走という爆弾も解消され、車載動画の撮影に最適です
ポイント
アプリ間でファイルを連携する場合、出力と入力でファイル指定のユーザ操作が必要となります。
今回は、アプリ間でのファイル連携をワンストップで実現する、ファイルを起動引数とした別アプリ(サービス)を起動する方法を紹介します。
起動引数の連携はClipDataを使用します。
ClipData
ClipData
ファイル指定のユーザ操作を必要としない出力先として、内部ストレージと外部ストレージがあります。
内部ストレージと外部ストレージはアプリ固有のストレージのため、別のアプリからアクセスできません。
アプリ間でファイル連携する場合、起動引数にファイル(Uri)をClipDataに格納、アプリを起動する必要があります。
起動する側
AndroidManifestに起動される側のアプリの情報と外部ストレージにアクセスするためのFileProviderを設定します。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
:
<queries>
<package android:name="com.jiseifirm.duel" />
:
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="*/*" />
</intent>
</queries>
:
<application
:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_path"/>
</provider>
</application>
</manifest>Intentに設定するActionはSEND、mimeTypeは連携するファイルがZipファイルのため”*/*”を設定します。
FileProviderのパス情報はxmlフォルダにprovider_path.xmlとして格納します。
<package>に起動される側のパッケージを登録する必要があります。
provider_path.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>アプリの起動はIntentを使用します。
IntentにActionと起動するアプリのパッケージ名、起動引数のClipDataにファイル(Uri)格納します。
// Zipファイルを起動引数にセットして、アプリを起動する
Intent intent = new Intent(Intent.ACTION_SEND).setPackage("com.jiseifirm.duel");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("application/zip");
intent.putExtra(Intent.EXTRA_STREAM, getUri(zip));
intent.setClipData(ClipData.newRawUri("", getUri(zip)));
startForegroundService(intent);
:
// Uri取得 //
public Uri getUri(String fileName, int type) {
Context context = getApplicationContext();
file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), fileName);
return FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", file);
}
:連携ファイルの格納先は外部ストレージのDocumentsフォルダを使用します。
起動される側
AndroidManifestに外部アプリから起動できるようにintent-filterを設定します。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
:
<application
:
<service
android:name="com.jiseifirm.duel.service.VideoService"
android:foregroundServiceType="dataSync"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="*/*"/>
</intent-filter>
</service>
:
:
</application>
</manifest>アプリ起動時にIntentから連携ファイルのUriを取得します。
public class VideoService extends Service {
private Uri EXTRA_STREAM;
private final Handler handler = new Handler(Looper.getMainLooper());
private ZipInputStream zipInputStream;
private BufferedOutputStream bufferedOutputStream;
private ZipEntry zipEntry;
private File zipFile;
private int len;
:
@Override
public int onStartCommand(@SuppressLint("UnsafeIntentLaunch") Intent intent, int flags, int startId) {
// 引数セット
EXTRA_STREAM = intent.getParcelableExtra(Intent.EXTRA_STREAM);
:
videoService();
return START_NOT_STICKY;
}
:
private void videoService() {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
try {
Uri fileUri = null;
zipInputStream = new ZipInputStream(context.getContentResolver().openInputStream(EXTRA_STREAM));
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
OutputStream outputStream = null;
ContentValues values = new ContentValues();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
values.put(MediaStore.MediaColumns.DISPLAY_NAME, zipEntry.getName());
values.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_MOVIES);
fileUri = context.getContentResolver().insert(MediaStore.Video.Media.getContentUri("external"), values);
outputStream = context.getContentResolver().openOutputStream(Objects.requireNonNull(fileUri));
} else {
zipFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).toString(), zipEntry.getName());
fileUri = Uri.fromFile(zipFile);
outputStream = Files.newOutputStream(zipFile.toPath());
}
if (outputStream != null) {
bufferedOutputStream = new BufferedOutputStream(outputStream);
byte[] buffer = new byte[1024];
while ((len = zipInputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, len);
}
bufferedOutputStream.close();
}
zipInputStream.closeEntry();
}
} catch (IOException e) {
// エラー処理
:
}
handler.post(() -> {
// 後処理
:
});
});
}
サンプルでは、連携ファイルが動画ファイル(mp4)の圧縮ファイル(Zip)です。
起動引数のUriを使用して、Zipファイルを解凍、メディアストアに登録しています。
今回は、ここまでです。
アプリ間でファイル連携しているAndroidアプリです。
誤字脱字、意味不明でわかりづらい、
もっと詳しく知りたいなどのご意見は、
このページの最後にあるコメントか、
こちらから、お願いいたします♪
ポチッとして頂けると、
次のコンテンツを作成する励みになります♪
これからAndroidのアプリ開発やJavaでの開発を始めたい方へ
アプリケーション開発経験がない方や、アプリケーション開発経験がある方でも、JavaやC#などのオブジェクト指向言語が初めての方は、Androidのアプリ開発ができるようになるには、かなりの時間がかかります。
オンラインスクールでの習得を、強くおススメします。
未経験者からプログラマーを目指すのに最適です。まずは無料カウンセリングから♪

ゲーム系に強いスクール、UnityやUnrealEngineを習得するのに最適です。まずは無料オンライン相談から♪

参考になったら、💛をポッチとしてね♪




コメント欄