Pocket

https://www.ninton.co.jp/?p=2738

その1とは別のアプリを targetSdkVersion=26にしたときの作業メモです。

// app/build.gradle

compileSdkVersion 27
buildToolsVersion 27.0.3
minSdkVersion 14
tartgetSdkVersion 19

ビルド1回め

$ ./gradlew clean
Downloading https://services.gradle.org/distributions/gradle-2.14.1-all.zip

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':app'.
> No toolchains found in the NDK toolchains folder for ABI with prefix: mipsel-linux-android

~/Android/Sdk/ndk-bundle/toolchains/ に、mipsel-linux-android がない、というエラーです。

その1では、gradle pluginを 3.1.4、gradleを4.4.1にして対応しました。

今回のアプリで、これをやると、次々と修正箇所がでてきて、サポートライブラリのAndroidXへの移行まで必要になりそうでした。今回は、なるべく簡単に済ませたいんです。

そこで、gradleはアップデートせず、~/Android/Sdk/ndk-bundle/toolchain/に mips用データを設置する方法にしました。

NDKアーカイブ を表示します。リビジョン18以降のパッケージには、MIPS用データがないので、リビジョン17c(2018年6月)のパッケージをダウンロードします。ぼくは、Linux 64 ビット をダウンロードしました。

ターミナルで作業します。

$ cd ~/Downloades
$ unzip android-ndk-r17c-linux-x86_64.zip

$ ls -1 android-ndk-r17c/toolchains/
NOTICE-MIPS
NOTICE-MIPS64
aarch64-linux-android-4.9
arm-linux-androideabi-4.9
llvm
mips64el-linux-android-4.9
mipsel-linux-android-4.9
renderscript
x86-4.9
x86_64-4.9

android−ndk−r17c/toolchains/ の下に、mips64el-linux-android-4.9/ と mipsel-linux-android-4.9/ があります。この2つを ~/Android/Sdk/ndk-bundle/toolchains/ 下に移動します。

$ mv ~/Downloads/android-ndk-r17c/toolchains/mips* ~/Android/Sdk/ndk-bundle/toolchains/

これでビルドできるようになりました。

カメラ起動でFileUriExposedException

カメラを起動すると、次のエラーが。

2019-07-16 14:52:20.004 10605-10605/com.myapp E/UncaughtException: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp/com.myapp.MainActivity}: android.os.FileUriExposedException: file:///storage/emulated/0/MyApp/2019-07-16_14-52-19_993.jpg exposed beyond app through ClipData.Item.getUri()
〜省略〜
     Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/MyApp/2019-07-16_14-52-19_993.jpg exposed beyond app through ClipData.Item.getUri()
〜省略〜

https://developer.android.com/training/camera/photobasics#java を見ると、カメラを起動するIntentに渡すファイルuriの作成方法が、Uri.fromFileから、FileProvider.getUriForFileに代わったようです。

Uri pictureUri = Uri.fromFile(pictureFile);
↓
Uri pictureUri = FileProvider.getUriForFile(this,getApplicationContext().getPackageName() + ".provider", pictureFile);
	

AndroidManifest.xmlにFileProvidorを設定します。

<application>
   ...
   <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.android.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"></meta-data>
    </provider>
    ...
</application>

res/xml/file_paths.xmlを新規作成します。

このアプリは、Environment.getExternalStorageDirectory() の下にカメラ画像を保存しているので、<external-path>を指定しました。

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="./" />
</paths>

FileProvider | Android Developers

タグ名場所
files-pathContext.getFilesDir()
cache-pathgetCacheDir()
external-pathEnvironment.getExternalStorageDirectory()
external-files-pathContext.getExternalFilesDir()
external-cache-pathContext.getExternalCacheDir()
external-media-pathContext.getExternalMediaDirs()

カメラを起動し、カメラ画像を保存できるようになりました。