getExternalFilesDir() はAndroid Q +では使用できないため、誰でもAndroid Qにファイルを保存する方法に関する正確なチュートリアルを公開できますか?.
私はこの問題に数日間取り組んできましたが、解決策を見つけることができません。
Webビューにロードするために、css、js、およびHTMLファイルをダウンロードしようとしています。
現在、Kotlinで記述された次のコードがあります。
_companion object {
private const val TAG = "MainActivity"
private var rootDir: Path? = null
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
...
rootDir = getExternalFilesDir(null)
Log.v(TAG, "RootDir: ${rootDir!!.path}")
val cacheDir = File(rootDir!!, "cache")
if(!cacheDir.exists()) {
Log.v(TAG, "Creating cache dir (${cacheDir.path})")
try {
if (cacheDir.mkdirs())
Log.v(TAG, "Created cache dir correctly")
else
Log.v(TAG, "Could not create cache dir")
}catch (ex: IOException){
Log.e(TAG, "Could not create cache dir: ", ex)
}catch (ex: SecurityException) {
Log.e(TAG, "Not allowed to create cache dir: ", ex)
}
}
val cssDir = File(cacheDir, "css")
if(!cssDir.exists()){
Log.v(TAG, "Creating css dir (${cssDir.path})")
try {
if (cacheDir.mkdirs())
Log.v(TAG, "Created css dir correctly")
else
Log.v(TAG, "Could not create css dir")
}catch (ex: IOException){
Log.e(TAG, "Could not create css dir: ", ex)
}catch (ex: SecurityException) {
Log.e(TAG, "Not allowed to create css dir: ", ex)
}
}
val siteGlobal = File(cssDir, "site_global.css")
if(!siteGlobal.exists())
DownloadFileAsyncTask().execute(DownloadFileAsyncTask.DownloadArgs("...", siteGlobal.path))
}
_
そして、DownloadFileAsyncTask:
_ private class DownloadFileAsyncTask :
AsyncTask<DownloadFileAsyncTask.DownloadArgs, Int, Void?>() {
data class DownloadArgs(val url : String, val savePath : String)
override fun doInBackground(vararg downloadFiles: DownloadArgs?): Void? {
for(downloadFile in downloadFiles) {
val urlStr = downloadFile!!.url
val outputFilePath = downloadFile.savePath
val outputFile = File(outputFilePath)
val url = URL(urlStr)
Log.v(TAG, "Connecting...")
val connection = url.openConnection() as HttpURLConnection
connection.connect()
if (connection.responseCode != HttpURLConnection.HTTP_OK) {
throw InterruptedException("Server returned HTTP ${connection.responseCode} ${connection.responseMessage}")
}
Log.v(TAG, "Connection correct")
if (!outputFile.exists()) {
Log.v(TAG, "Creating ${outputFile.path}")
outputFile.createNewFile()
}
val fileLength = connection.contentLength
val input = connection.inputStream
val output = FileOutputStream(outputFile)
val data = ByteArray(4096)
var total: Long = 0
var count: Int
Log.v(TAG, "Starting download...")
while (true) {
count = input.read(data)
if (count < 0) break
total += count
if (fileLength > 0)
publishProgress((total * 10 / fileLength).toInt())
output.write(data, 0, count)
}
output.close()
input?.close()
connection.disconnect()
}
return null
}
}
_
そして、Logcatに関する私の応答は次のとおりです。
_V/MainActivity: RootDir: /storage/emulated/0/Android/data/.../files
V/MainActivity: Creating cache dir (/storage/emulated/0/Android/data/.../files/cache)
V/MainActivity: Created cache dir correctly
V/MainActivity: Creating css dir (/storage/emulated/0/Android/data/.../files/cache/css)
V/MainActivity: Could not create css dir
V/MainActivity: Connecting...
V/MainActivity: Connection correct
V/MainActivity: Creating /storage/emulated/0/Android/data/.../files/cache/css/site_global.css
_
そして明らかに、ディレクトリが存在しないため、AsyncTaskのoutputFile.createNewFile()
で_Java.io.IOException: No such file or directory
_でクラッシュします。
フォルダーの作成に関するエラーは表示されないため、ディレクトリを作成できなかったことが示されるだけで、何が問題なのかわかりません。
問題が発生した場合に備えて_<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />
_を追加して許可しましたが、何も解決しませんでした。
getExternalStorageDirectory()
はAPI-29で廃止されました
ステップを確認してください
FTPサーバーからAndroidデバイス? にファイルをダウンロードする方法
//private static void createFile(Context ctx, String fileName, byte text)
private static void createFile(Context ctx, String fileName, String text) {
File filesDir = ctx.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
assert filesDir != null;
if (!filesDir.exists()){
if(filesDir.mkdirs()){
}
}
File file = new File(filesDir, fileName);
try {
if (!file.exists()) {
if (!file.createNewFile()) {
throw new IOException("Cant able to create file");
}
}
OutputStream os = new FileOutputStream(file);
byte[] data = text.getBytes();
os.write(data);
os.close();
Log.e("TAG", "File Path= " + file.toString());
} catch (IOException e) {
e.printStackTrace();
}
}