OSDN Git Service

181377ac0743f5c470b44c97e69e9c97391c2e53
[gokigen/MeMoMa.git] / app / src / main / java / jp / sourceforge / gokigen / memoma / io / MeMoMaFileExportCsvProcess.java
1 package jp.sourceforge.gokigen.memoma.io;
2
3 import static jp.sourceforge.gokigen.memoma.Main.APP_NAMESPACE;
4
5 import java.io.File;
6 import java.io.OutputStream;
7 import java.io.OutputStreamWriter;
8 import java.text.SimpleDateFormat;
9 import java.util.Calendar;
10 import java.util.Enumeration;
11 import java.util.Locale;
12
13 import android.app.ProgressDialog;
14 import android.content.ContentResolver;
15 import android.content.ContentValues;
16 import android.content.Context;
17 import android.graphics.RectF;
18 import android.net.Uri;
19 import android.os.AsyncTask;
20 import android.os.Build;
21 import android.os.Environment;
22 import android.provider.MediaStore;
23 import android.util.Log;
24
25 import jp.sourceforge.gokigen.memoma.R;
26 import jp.sourceforge.gokigen.memoma.holders.MeMoMaObjectHolder;
27 import jp.sourceforge.gokigen.memoma.holders.PositionObject;
28
29 /**
30  *  データをファイルに保存するとき用 アクセスラッパ (非同期処理を実行)
31  */
32 public class MeMoMaFileExportCsvProcess extends AsyncTask<MeMoMaObjectHolder, Integer, String>
33 {
34     private final String TAG = toString();
35     private final Context context;
36     private final IResultReceiver receiver;
37     private String exportedFileName = null;
38
39     private final ProgressDialog savingDialog;
40
41     /**
42      *   コンストラクタ
43      */
44     public MeMoMaFileExportCsvProcess(Context context,  IResultReceiver resultReceiver)
45     {
46         this.context = context;
47         receiver = resultReceiver;
48
49         //  プログレスダイアログ(「保存中...」)を表示する。
50         savingDialog = new ProgressDialog(context);
51         savingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
52         savingDialog.setMessage(context.getString(R.string.dataSaving));
53         savingDialog.setIndeterminate(true);
54         savingDialog.setCancelable(false);
55         savingDialog.show();
56
57
58     }
59
60     /**
61      *  非同期処理実施前の前処理
62      *
63      */
64     @Override
65     protected void onPreExecute()
66     {
67
68     }
69
70     /**
71      *    データを(CSV形式で)保管する。
72      *
73      */
74     private String exportToCsvFile(String baseName, MeMoMaObjectHolder objectHolder)
75     {
76         String resultMessage = "";
77         try
78         {
79             String outputDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + "/" + APP_NAMESPACE + "/";
80             ContentResolver resolver = context.getContentResolver();
81
82             // エクスポートするファイル名を決定する
83             Calendar calendar = Calendar.getInstance();
84             SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMdd_HHmmss_", Locale.US);
85             exportedFileName =  outFormat.format(calendar.getTime()) + baseName + ".csv";
86
87             Uri extStorageUri;
88             ContentValues values = new ContentValues();
89             values.put(MediaStore.Downloads.TITLE, exportedFileName);
90             values.put(MediaStore.Downloads.DISPLAY_NAME, exportedFileName);
91             values.put(MediaStore.Downloads.MIME_TYPE, "text/csv"); // text/plain or text/csv
92             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
93             {
94                 values.put(MediaStore.Downloads.RELATIVE_PATH, "Download/" + APP_NAMESPACE);
95                 values.put(MediaStore.Downloads.IS_PENDING, true);
96                 extStorageUri = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
97             }
98             else
99             {
100                 File path = new File(outputDir);
101                 values.put(MediaStore.Downloads.DATA, path.getAbsolutePath() + File.separator + exportedFileName);
102                 extStorageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
103             }
104             Log.v(TAG, "---------- " + exportedFileName + " " + values);
105
106             Uri documentUri = resolver.insert(extStorageUri, values);
107
108             if (documentUri == null)
109             {
110                 resultMessage = "documentUri is NULL.";
111                 return (resultMessage);
112             }
113
114             OutputStream outputStream = resolver.openOutputStream(documentUri, "wa");
115             OutputStreamWriter writer = new OutputStreamWriter(outputStream);
116
117             //  データのタイトルを出力
118             String str = "; label,detail,userChecked,shape,style,centerX,centerY,width,height,;!<_$ (';!<_$' is a record Separator)\r\n";
119             writer.write(str);
120
121             // オブジェクトの出力 (保持しているものをすべて表示する)
122             Enumeration<Integer> keys = objectHolder.getObjectKeys();
123             while (keys.hasMoreElements())
124             {
125                 Integer key = keys.nextElement();
126                 PositionObject pos = objectHolder.getPosition(key);
127                 RectF posRect = pos.getRect();
128
129                 // TODO:  絞り込み条件がある場合には、その条件に従ってしぼり込む必要あり。
130
131                 str = "";
132                 str = str + "\"" + pos.getLabel() + "\"";
133                 str = str + ",\"" + pos.getDetail() + "\"";
134                 if (pos.getUserChecked())
135                 {
136                     str = str + ",True";
137                 }
138                 else
139                 {
140                     str = str + ",False";
141                 }
142                 str = str + "," + pos.getDrawStyle();   // オブジェクトの形状
143                 str = str + "," + pos.getPaintStyle();   // オブジェクトの塗りつぶし状態
144                 str = str + "," + (Math.round(posRect.centerX() * 100.0f) / 100.0f);
145                 str = str + "," + (Math.round(posRect.centerY() * 100.0f) / 100.0f);
146                 str = str + "," + (Math.round(posRect.width() * 100.0f) / 100.0f);
147                 str = str + "," + (Math.round(posRect.height() * 100.0f) / 100.0f);
148                 str = str + ",;!<_$\r\n";
149                 writer.write(str);
150             }
151             writer.flush();
152             writer.close();
153
154             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
155             {
156                 values.put(MediaStore.Downloads.IS_PENDING, false);
157                 resolver.update(documentUri, values, null, null);
158             }
159         }
160         catch (Exception e)
161         {
162             resultMessage = " ERR " + e.getMessage();
163             Log.v(TAG, resultMessage);
164             e.printStackTrace();
165         }
166         return (resultMessage);
167     }
168
169     /**
170      *  非同期処理
171      *  (バックグラウンドで実行する(このメソッドは、UIスレッドと別のところで実行する))
172      *
173      */
174     @Override
175     protected String doInBackground(MeMoMaObjectHolder... datas)
176     {
177         // ファイル名の設定 ... (拡張子なし)
178         String fileName = context.getFilesDir() + "/exported/" + datas[0].getDataTitle();
179
180         // データを保管する
181         String result = exportToCsvFile(fileName, datas[0]);
182
183         System.gc();
184
185         return (result);
186     }
187
188     /**
189      *  非同期処理の進捗状況の更新
190      *
191      */
192     @Override
193     protected void onProgressUpdate(Integer... values)
194     {
195         // 今回は何もしない
196     }
197
198     /**
199      *  非同期処理の後処理
200      *  (結果を応答する)
201      */
202     @Override
203     protected void onPostExecute(String result)
204     {
205         try
206         {
207             if (receiver != null)
208             {
209                 receiver.onExportedResult(exportedFileName, result);
210             }
211         }
212         catch (Exception ex)
213         {
214             Log.v(TAG, "MeMoMaFileExportCsvProcess::onPostExecute() : " + ex.toString());
215         }
216         // プログレスダイアログを消す
217         savingDialog.dismiss();
218     }
219
220     /**
221      *    結果報告用のインタフェース(積極的に使う予定はないけど...)
222      *
223      * @author MRSa
224      *
225      */
226     public interface IResultReceiver
227     {
228         /**  保存結果の報告 **/
229         void onExportedResult(String exportedFileName, String detail);
230     }
231 }