質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

6866閲覧

Android ファイルの移動/ループ処理

xxx8

総合スコア41

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

1クリップ

投稿2017/11/07 00:19

編集2017/11/07 02:35

###前提(環境)
AndroidStudio2.3.3
SDK 7.1.1 
API 25
targetSDK 25

###実現したいこと
内部ストレージ/フォルダA内のファイル10枚を
外部ストレージ/Android/data/自パッケージ/フォルダBに移動させたいです。

###発生している問題(わからないこと)
・ファイルを移動するやりかたがわかりません。
・.listFiles()でファイル一覧を配列で取得してから指定数分のループ処理をすればいいので しょうか?

###該当のソースコード

java

1 2// 移動元フォルダ 3File from = new File("strage"+"sample"+"A"); 4 5// 移動先フォルダ 6File to = new File("strage"+"/Android/"+"/data/"+"/<自パッケージ>/"+"B"); 7 8for (int i = 0; i < 10; i++) { 9 10 // 存在チェック 11 if (!to .exists()) { 12 if (!to .mkdirs()) { 13 LogWriter.writeLog(LogWriter.sReleaseMode, "ディレクトリの作成に失敗しました"); 14 return; 15 } 16 }

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keicha_hrs

2017/11/07 02:24

以前の質問で、AndroidにおけるファイルI/Oの困難さは十分理解されたのではないのでしょうか。どの場所にあるファイルをどこに移動したいのかで回答は異なることも承知されていると思うのですが、この雑な質問はどうしたことなのでしょうか。
xxx8

2017/11/07 02:34

情報が抜けてました。すみません。  今回は内部ストレージ内のファイルから外部ストレージの特別扱いとなる<自パッケージ>へのファイルの移動をさせたいです。
guest

回答1

0

ベストアンサー

いろいろ要点がありそうです。

まず、ファイル移動は時間のかかる作業になります。Androidのライフサイクルによるイベントメソッド(onCreateのような)は、迅速に処理を終えないとアプリが落ちてしまいます。小さなファイル1個を読み書きする程度なら問題ないのですが、10個のファイルだと別スレッドを設けないと、落ちる可能性が高いと思います。

別スレッドを作るには、ThreadやAsyncTaskを使う方法がありますが、AsyncTaskを使うならばこの辺を参考にすればいいでしょうか。doInBackgroundというメソッドが非同期で動作するスレッドの本体になるので、この中にファイル移動のループ処理を実装すればいいでしょう。

次に、内部ストレージから読み出すためには、前回の質問のようにRuntime Premissionによって読み取りの許可を得る必要があります。File#listFilesで一覧を取得しようとするのは間違いではないのですが、許可を得ていないとlistFilesの戻り値がnullになってしまうので、この時点でコケてしまいます。

その上で、内部ストレージのパスを得るのは、

Java

1 File from = new File(Environment.getExternalStorageDirectory() + "/sample/A");

(11/08 23:46 訂正)
パスの直接記述は推奨されません。うっかり直接記述で回答してしまいましたが、内部ストレージのパスを得るにはEnvironment.getExternalStorageDirectory()を用いるべきなので、訂正しました。
(訂正おわり)

のようにすればいいでしょう。区切り記号の/は自動的には挿入されないので、ディレクトリー名の文字列を単純に繋ぐだけではだめです。これで得られた変数fromから

Java

1 File[] files = from.listFiles();

のようにすれば、filesという変数にこのディレクトリーに入っているファイル一覧が得られるでしょう。

次に、外部ストレージ(以下、SDカード)のパッケージ専用ディレクトリーのパスを得るには、Context#getExternalFilesDirsを用いましょう。SDカードのパス名は/storage/<SDカードのUUID>/という構成になっています。UUIDはSDカードごとに異なる一意の値になるので、SDカードを差し替えると別の値になります。ここを決め打ちしてしまうと、「今差しているSDカードでしか動かないプログラム」になってしまいます。それでは多分困るでしょう。

ここは

Java

1 File sdcarddir = null; 2 File[] dirs = getExternalFilesDirs(null); 3 for (File dir : dirs) { 4 if (Environment.isExternalStorageRemovable(dir)) { 5 sdcarddir = new File(dir + "/sample/B"); 6 break; 7 } 8 }

のようにすれば、sdcarddirという変数に/storage/<SDカードのUUID>/Android/data/<パッケージ名>/files/sample/Bというパスが得られるでしょう。ちなみに、Environment.isExternalStorageRemovableというのは、取り外し可能メディアであるかを判別するためのメソッドです。これを用いて、簡易的にSDカードかどうかを判定しています。本当はもっと念を入れて確認した方が良いようですが、まあ試験的にやってみる程度なら。

getExternalFilesDirsの引数をnullにすると、パッケージ名の下にさらにfilesディレクトリーがくっつくのですが、パッケージ名の直下に置かれるディレクトリーには役割があるので、特殊な事情でもない限りはそれに従うのが良策と思います。

で、最後にファイル移動ですが、一般的にはFile#renameToというメソッドを使う方法がありますが、「内部ストレージからSDカード」のような異なるメディア間の移動には使えないようなので(常識なのかな?)、単純に「コピー元ファイルの内容を全部読み取ってコピー先ファイルに書き出す」みたいな作業になってしまうのではないでしょうか。このサイトの「java.io.Fileクラスを使用してコピーする」として紹介されているような感じでしょうか。ここは他にもいろいろ方法はありそうですが。

実際に軽く作ってみましたが、上記のような方針で思ったような結果は得られるようです。(実現できないことを回答してしまうほど恥ずかしいことはない。)

ものすご〜〜〜〜く長い回答で申し訳ないのだけど、この辺の要点を一つ一つクリアしながら作成してみてはいかがでしょうか。一気にゴールを目指そうとしないことです。アプリ開発は基礎知識の積み重ねですから。

投稿2017/11/07 15:54

編集2017/11/08 14:54
keicha_hrs

総合スコア6766

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xxx8

2017/11/07 23:45

とてもわかりやすいご説明ありがとうございます。 ただ1つ、「パッケージ名の直下に置かれるディレクトリーには役割があるので・・・」というのは、 むやみにパッケージ名の直下にフォルダを作らないほうがいいということでしょうか><?
keicha_hrs

2017/11/08 10:05 編集

単純に「パッケージ名まで止まりのパス」を取得するAPIがないだけなんですけどね。getExternalFilesDirs(null)で得られたパスからfilesだけ削るとか、どうしても一手間必要になります(大した手間でもないんだが)。その手間を割けるなら、パッケージ名直下にディレクトリーを作っても構わないとは思います。
xxx8

2017/11/10 01:53

ありがとうごいます><
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問