<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/Theme.AppCompat">
<activity android:name=".Main"
android:exported="true">
package jp.sourceforge.gokigen.memoma
+import android.Manifest
import android.app.Dialog
import android.content.Intent
+import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.Window
+import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
import jp.sourceforge.gokigen.memoma.io.MeMoMaDataInOutManager
/**
{
e.printStackTrace()
}
+
+ try
+ {
+ if (!allPermissionsGranted())
+ {
+ ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+
Log.v(TAG, " START MEMOMA...");
}
}
return false
}
-
+ private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
+ ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED
+ }
/**
* 画面が裏に回ったときの処理
*/
}
}
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray)
+ {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ if (requestCode == REQUEST_CODE_PERMISSIONS)
+ {
+ if (!allPermissionsGranted())
+ {
+ Toast.makeText(this, getString(R.string.permission_not_granted), Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
companion object {
const val APP_NAMESPACE = "gokigen"
private val TAG = Main::class.java.simpleName
+ private const val REQUEST_CODE_PERMISSIONS = 10
+ private val REQUIRED_PERMISSIONS = arrayOf(
+ Manifest.permission.READ_EXTERNAL_STORAGE,
+ )
}
}
// データ表示用Activityを起動する
parent.startActivityForResult(intent, MENU_ID_EXTEND);
+ //parent.startActivity(intent);
}
/**
package jp.sourceforge.gokigen.memoma.extension;
-import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
{
e.printStackTrace();
}
- return (super.onCreateOptionsMenu(menu));
+ return (super.onCreateOptionsMenu(menu));
}
-
+
/**
* メニューアイテムの選択
*/
{
e.printStackTrace();
}
- return (super.onPrepareOptionsMenu(menu));
+ return (super.onPrepareOptionsMenu(menu));
}
/**
}
/**
- * ダイアログ表示の準備
- *
- */
- @Override
- protected Dialog onCreateDialog(int id)
- {
- return (listener.onCreateDialog(id));
- }
-
- /**
- * ダイアログ表示の準備
- *
- */
- @Override
- protected void onPrepareDialog(int id, Dialog dialog)
- {
- try
- {
- listener.onPrepareDialog(id, dialog);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- /**
* 子画面から応答をもらったときの処理
*/
@Override
import java.util.Locale;
import android.app.Activity;
-import android.app.Dialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
-import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ListAdapter;
import android.widget.ListView;
{
private final String TAG = toString();
private static final int PICK_CSV_FILE = 2020;
+ private static final int PICK_XML_FILE = 2030;
+
private final int MENU_ID_EXPORT= (Menu.FIRST + 1);
- private final int MENU_ID_SHARE = (Menu.FIRST + 2);
- private final int MENU_ID_IMPORT = (Menu.FIRST + 3);
+ private final int MENU_ID_EXPORT_XML = (Menu.FIRST + 2);
+ private final int MENU_ID_SHARE = (Menu.FIRST + 3);
+ private final int MENU_ID_IMPORT = (Menu.FIRST + 4);
+ private final int MENU_ID_IMPORT_XML = (Menu.FIRST + 5);
+ private final int MENU_ID_DELETE = (Menu.FIRST + 6);
private final MeMoMaObjectHolder objectHolder;
- private FileSelectionDialog fileSelectionDialog = null;
-
+ //private FileSelectionDialog fileSelectionDialog = null;
private boolean isShareExportedData = false;
-
private List<SymbolListArrayItem> listItems = null;
-
private final AppCompatActivity parent; // 親分
/**
}
catch (Exception ex)
{
- Log.v(TAG, "Exception :" + ex.toString());
+ Log.v(TAG, "Exception :" + ex.getMessage());
}
}
/**
* がっつりこのクラスにイベントリスナを接続する
- *
*/
public void prepareListener()
{
{
}
-
+
+ private void imporObjectFromCsv(final Uri uri)
+ {
+ try
+ {
+ // Perform operations on the document using its URI.
+ Thread thread = new Thread(() -> {
+ ExtensionCsvImport importer = new ExtensionCsvImport(parent, objectHolder, uri);
+ importer.importFromCsvFile();
+
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
+ String backgroundUri = preferences.getString("backgroundUri","");
+ String userCheckboxString = preferences.getString("userCheckboxString","");
+
+ // データの保管メイン
+ MeMoMaFileSavingEngine savingEngine = new MeMoMaFileSavingEngine(parent, backgroundUri, userCheckboxString);
+ String result = savingEngine.saveObjects(objectHolder);
+ parent.runOnUiThread(() -> {
+ try
+ {
+ onImportedResult(result);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ });
+ });
+ thread.start();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void importDataFromXml(final Uri uri)
+ {
+ try
+ {
+ // Perform operations on the document using its URI.
+ Thread thread = new Thread(() -> {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
+ String backgroundUri = preferences.getString("backgroundUri","");
+ String userCheckboxString = preferences.getString("userCheckboxString","");
+
+ // データの保管を実施する (現状)
+ MeMoMaFileSavingEngine savingEngine = new MeMoMaFileSavingEngine(parent, backgroundUri, userCheckboxString);
+ String result0 = savingEngine.saveObjects(objectHolder);
+ Log.v(TAG, "Saved : " + result0);
+
+ //
+ ExtensionXmlImport importer = new ExtensionXmlImport(parent, objectHolder, uri);
+ String result1 = importer.importFromXmlFile();
+
+ // データの保管を実施する (新規)
+ MeMoMaFileSavingEngine savingEngine2 = new MeMoMaFileSavingEngine(parent, backgroundUri, userCheckboxString);
+ String result = savingEngine2.saveObjects(objectHolder) + " " + result1;
+ Log.v(TAG, "=== Data Saved : " + objectHolder.getDataTitle() + " " + result + " " + result1);
+ parent.runOnUiThread(() -> {
+ try
+ {
+ // 読み込んだファイル名をタイトルに設定する
+ parent.setTitle(objectHolder.getDataTitle());
+
+ // タイトルバーの更新...
+ ActionBar bar = parent.getSupportActionBar();
+ if (bar != null)
+ {
+ bar.setIcon(R.drawable.icon1);
+ bar.setTitle(objectHolder.getDataTitle());
+ bar.show();
+ }
+ onImportedResultXml(result);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ });
+ });
+ thread.start();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
/**
* 他画面から戻ってきたとき...
*/
{
try
{
- if ((requestCode == PICK_CSV_FILE)&&(resultCode == Activity.RESULT_OK))
+ if (resultCode == Activity.RESULT_OK)
{
if (resultData != null)
{
Uri uri = resultData.getData();
- Log.v(TAG, "========== rc: " + requestCode + " rs: " + resultCode + " uri: " + uri.toString());
-
- // Perform operations on the document using its URI.
- Thread thread = new Thread(() -> {
- ExtensionCsvImport importer = new ExtensionCsvImport(parent, objectHolder, uri);
- importer.importFromCsvFile();
-
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
- String backgroundUri = preferences.getString("backgroundUri","");
- String userCheckboxString = preferences.getString("userCheckboxString","");
-
- // データの保管メイン
- MeMoMaFileSavingEngine savingEngine = new MeMoMaFileSavingEngine(parent, backgroundUri, userCheckboxString);
- String result = savingEngine.saveObjects(objectHolder);
-
- parent.runOnUiThread(() -> {
- try
- {
- onImportedResult(result);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- });
- });
- try
+ if (requestCode == PICK_CSV_FILE)
+ {
+ imporObjectFromCsv(uri);
+ }
+ else if (requestCode == PICK_XML_FILE)
{
- thread.start();
+ importDataFromXml(uri);
}
- catch (Exception ee)
+ else
{
- ee.printStackTrace();
+ Log.v(TAG, "========== rc: " + requestCode + " rs: " + resultCode + " uri: " + uri.toString());
}
}
}
menuItem = menu.add(Menu.NONE, MENU_ID_IMPORT, Menu.NONE, parent.getString(R.string.import_csv));
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menuItem.setIcon(android.R.drawable.ic_menu_edit);
+
+ menuItem = menu.add(Menu.NONE, MENU_ID_EXPORT_XML, Menu.NONE, parent.getString(R.string.export_xml));
+ menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ menuItem.setIcon(android.R.drawable.ic_menu_send);
+
+ menuItem = menu.add(Menu.NONE, MENU_ID_IMPORT_XML, Menu.NONE, parent.getString(R.string.import_xml));
+ menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ menuItem.setIcon(android.R.drawable.ic_menu_add);
+
+ menuItem = menu.add(Menu.NONE, MENU_ID_DELETE, Menu.NONE, parent.getString(R.string.delete_content));
+ menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ menuItem.setIcon(android.R.drawable.ic_menu_delete);
+
}
catch (Exception e)
{
{
menu.findItem(MENU_ID_SHARE).setVisible(true);
menu.findItem(MENU_ID_EXPORT).setVisible(true);
+ menu.findItem(MENU_ID_EXPORT_XML).setVisible(true);
menu.findItem(MENU_ID_IMPORT).setVisible(true);
+ menu.findItem(MENU_ID_IMPORT_XML).setVisible(true);
+ menu.findItem(MENU_ID_DELETE).setVisible(true);
}
catch (Exception e)
{
export_as_csv(false);
result = true;
}
+ case MENU_ID_EXPORT_XML -> {
+ // 表示中データのエクスポート
+ export_as_xml();
+ result = true;
+ }
case MENU_ID_SHARE -> {
export_as_csv(true);
result = true;
importObjectFromCsv();
result = true;
}
+ case MENU_ID_IMPORT_XML -> {
+ // データのインポート(XML形式)
+ importObjectFromXml();
+ result = true;
+ }
+ case MENU_ID_DELETE -> {
+ // データの削除
+ deleteContent();
+ result = true;
+ }
default -> result = false;
}
return (result);
}
+ /**
+ * XML形式でデータをインポートする
+ */
+ private void importObjectFromXml()
+ {
+ try
+ {
+ // ファイル選択のダイアログを取得する
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
+ {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("text/*");
+ intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
+ {
+ String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + "/" + APP_NAMESPACE + "/";
+ intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, path);
+ }
+ parent.startActivityForResult(intent, PICK_XML_FILE);
+ }
+ else
+ {
+ // 旧バージョンの Android での処理... (File Picker ってあったっけ?)
+
+
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * データを削除する
+ */
+ private void deleteContent()
+ {
+ try
+ {
+ // データの一覧を取得する
+
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
/**
* CSV形式でデータをインポートする
MeMoMaFileExportCsvProcess asyncTask = new MeMoMaFileExportCsvProcess(parent, this);
asyncTask.execute(objectHolder);
}
-
- /**
- * ダイアログの生成
- */
- public Dialog onCreateDialog(int id)
- {
- if (id == R.id.listdialog)
- {
- fileSelectionDialog = new FileSelectionDialog(parent, parent.getString(R.string.dialogtitle_selectcsv), ".csv", this);
- return (fileSelectionDialog.getDialog());
- }
- return (null);
- }
/**
- * ファイル選択ダイアログの表示を準備する
- *
+ * データをXML形式で出力する
*/
- private void prepareFileSelectionDialog(Dialog dialog)
+ private void export_as_xml()
{
try
{
- Log.v(TAG, " " + dialog.toString());
- fileSelectionDialog.prepare();
+ Thread thread = new Thread(() -> {
+ try
+ {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
+ String backgroundUri = preferences.getString("backgroundUri", "");
+ String userCheckboxString = preferences.getString("userCheckboxString", "");
+ ExtensionXmlExport exporter = new ExtensionXmlExport(parent, objectHolder, backgroundUri, userCheckboxString);
+ final String result = exporter.exportToXmlFile();
+ parent.runOnUiThread(() -> {
+ try
+ {
+ onExportedResultXml(result);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ });
+ }
+ catch (Exception ee)
+ {
+ ee.printStackTrace();
+ }
+ });
+ thread.start();
}
catch (Exception e)
{
}
/**
- * ダイアログ表示の準備
- *
- */
- public void onPrepareDialog(int id, Dialog dialog)
- {
- if (id == R.id.listdialog)
- {
- // CSVインポートダイアログを準備する
- prepareFileSelectionDialog(dialog);
- }
- }
-
- /**
* ファイルをロードする途中のバックグラウンド処理...
*
*/
*/
public void onExportedResult(Uri documentUri, String detail)
{
- Log.v(TAG, "ExtensionActivityListener::onExportedResult() '" + objectHolder.getDataTitle() +"' : " + detail);
+ Log.v(TAG, "ExtensionActivityListener::onExportedResult() '" + objectHolder.getDataTitle() +"' : " + detail);
- // エクスポートしたことを伝達する
- String outputMessage = parent.getString(R.string.export_csv) + " " + objectHolder.getDataTitle() + " " + detail;
+ // エクスポートしたことを伝達する
+ String outputMessage = parent.getString(R.string.export_csv) + " " + objectHolder.getDataTitle() + " " + detail;
Toast.makeText(parent, outputMessage, Toast.LENGTH_SHORT).show();
-
+
if (isShareExportedData)
{
- // エクスポートしたファイルを共有する
+ // エクスポートしたファイルを共有する
shareContent(documentUri);
}
- isShareExportedData = false;
+ isShareExportedData = false;
}
/**
listView.setAdapter(adapter);
// アイテムを選択したときの処理
- listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- //@Override
- public void onItemClick(AdapterView<?> parentView, View view, int position, long id)
- {
- ListView listView = (ListView) parentView;
- SymbolListArrayItem item = (SymbolListArrayItem) listView.getItemAtPosition(position);
+ listView.setOnItemClickListener((parentView, view, position, id) -> {
+ ListView listView1 = (ListView) parentView;
+ SymbolListArrayItem item = (SymbolListArrayItem) listView1.getItemAtPosition(position);
- /// リストが選択されたときの処理...データを開く
- showDetailData(item.getTextResource1st(), item.getTextResource2nd(), item.getTextResource3rd());
- }
+ /// リストが選択されたときの処理...データを開く
+ showDetailData(item.getTextResource1st(), item.getTextResource2nd(), item.getTextResource3rd());
});
System.gc(); // いらない(参照が切れた)クラスを消したい
}
// 一覧のリストを作りなおす
onLoadingProcess();
updateObjectList();
- }
+ }
+
+ private void onImportedResultXml(String detail)
+ {
+ Log.v(TAG, "ExtensionActivityListener::onImportedResultXml() '" + objectHolder.getDataTitle() +"' : " + detail);
+
+ // インポートしたことを伝達する
+ String outputMessage = parent.getString(R.string.import_xml) + " " + objectHolder.getDataTitle() + " " + detail;
+ Toast.makeText(parent, outputMessage, Toast.LENGTH_SHORT).show();
+
+ // 一覧のリストを作りなおす
+ onLoadingProcess();
+ updateObjectList();
+ }
+ private void onExportedResultXml(String detail)
+ {
+ Log.v(TAG, "ExtensionActivityListener::onExportedResultXml() '" + objectHolder.getDataTitle() +"' : " + detail);
+
+ // エクスポートしたことを伝達する
+ String outputMessage = parent.getString(R.string.export_xml) + " " + objectHolder.getDataTitle() + " " + detail;
+ Toast.makeText(parent, outputMessage, Toast.LENGTH_SHORT).show();
+ }
+
}
import java.io.InputStream
import java.io.InputStreamReader
-
class ExtensionCsvImport(private val context: Context, private val objectHolder: MeMoMaObjectHolder, private val importUri: Uri)
{
fun importFromCsvFile()
companion object {
private val TAG = ExtensionCsvImport::class.java.simpleName
}
-
}
\ No newline at end of file
--- /dev/null
+package jp.sourceforge.gokigen.memoma.extension
+
+import android.content.ContentValues
+import android.content.Context
+import android.net.Uri
+import android.os.Build
+import android.os.Environment
+import android.provider.MediaStore
+import android.util.Log
+import android.util.Xml
+import jp.sourceforge.gokigen.memoma.Main
+import jp.sourceforge.gokigen.memoma.holders.MeMoMaObjectHolder
+import java.io.File
+import java.io.OutputStreamWriter
+import java.text.SimpleDateFormat
+import java.util.Calendar
+import java.util.Locale
+
+class ExtensionXmlExport(private val context: Context, private val objectHolder: MeMoMaObjectHolder, private val backgroundUri: String, private val userCheckboxString: String)
+{
+ fun exportToXmlFile(): String
+ {
+ var resultMessage = ""
+ try
+ {
+ val outputDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path + "/" + Main.APP_NAMESPACE + "/"
+ val resolver = context.contentResolver
+
+ // エクスポートするファイル名を決定する
+ val calendar = Calendar.getInstance()
+ val outFormat = SimpleDateFormat("yyyyMMdd_HHmmss_", Locale.US)
+ val exportedFileName = outFormat.format(calendar.time) + objectHolder.dataTitle + ".xml"
+ val extStorageUri: Uri
+ val values = ContentValues()
+ values.put(MediaStore.Downloads.TITLE, exportedFileName)
+ values.put(MediaStore.Downloads.DISPLAY_NAME, exportedFileName)
+ values.put(MediaStore.Downloads.MIME_TYPE, "text/xml") // text/plain or text/xml
+ extStorageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+ {
+ values.put(MediaStore.Downloads.RELATIVE_PATH, "Download/" + Main.APP_NAMESPACE)
+ values.put(MediaStore.Downloads.IS_PENDING, true)
+ MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
+ }
+ else
+ {
+ val path = File(outputDir)
+ values.put(MediaStore.Downloads.DATA, path.absolutePath + File.separator + exportedFileName)
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ }
+ Log.v(TAG, "---------- $exportedFileName $values")
+ val documentUri = resolver.insert(extStorageUri, values)
+ if (documentUri == null)
+ {
+ resultMessage = "documentUri is NULL."
+ return resultMessage
+ }
+ val outputStream = resolver.openOutputStream(documentUri, "wa")
+ val writer = OutputStreamWriter(outputStream)
+ val serializer = Xml.newSerializer()
+ serializer.setOutput(writer)
+ serializer.startDocument("UTF-8", true)
+ serializer.startTag(Main.APP_NAMESPACE, "memoma")
+
+ // タイトルの出力
+ serializer.startTag(Main.APP_NAMESPACE, "title")
+ serializer.text(objectHolder.dataTitle)
+ serializer.endTag(Main.APP_NAMESPACE, "title")
+
+ // 背景情報の出力
+ serializer.startTag(Main.APP_NAMESPACE, "background")
+ serializer.text(objectHolder.background)
+ serializer.endTag(Main.APP_NAMESPACE, "background")
+
+ // 背景画像URIの出力
+ serializer.startTag(Main.APP_NAMESPACE, "backgroundUri")
+ serializer.text(backgroundUri)
+ serializer.endTag(Main.APP_NAMESPACE, "backgroundUri")
+
+ // ユーザチェックボックス名の出力
+ serializer.startTag(Main.APP_NAMESPACE, "userCheckboxString")
+ serializer.text(userCheckboxString)
+ serializer.endTag(Main.APP_NAMESPACE, "userCheckboxString")
+
+ serializer.startTag(Main.APP_NAMESPACE, "objserial")
+ serializer.text(objectHolder.serialNumber.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "objserial")
+
+ serializer.startTag(Main.APP_NAMESPACE, "lineserial")
+ serializer.text(objectHolder.connectLineHolder.serialNumber.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "lineserial")
+
+ // オブジェクトの出力 (保持しているものはすべて表示する)
+ val keys = objectHolder.objectKeys
+ while (keys.hasMoreElements())
+ {
+ val key = keys.nextElement()
+ val pos = objectHolder.getPosition(key)
+ val posRect = pos.rect
+ serializer.startTag(Main.APP_NAMESPACE, "object")
+ serializer.attribute(Main.APP_NAMESPACE, "key", key.toString())
+ serializer.startTag(Main.APP_NAMESPACE, "rect")
+ serializer.startTag(Main.APP_NAMESPACE, "top")
+ serializer.text(posRect.top.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "top")
+ serializer.startTag(Main.APP_NAMESPACE, "left")
+ serializer.text(posRect.left.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "left")
+ serializer.startTag(Main.APP_NAMESPACE, "right")
+ serializer.text(posRect.right.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "right")
+ serializer.startTag(Main.APP_NAMESPACE, "bottom")
+ serializer.text(posRect.bottom.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "bottom")
+ serializer.endTag(Main.APP_NAMESPACE, "rect")
+ serializer.startTag(Main.APP_NAMESPACE, "drawStyle")
+ serializer.text(pos.drawStyle.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "drawStyle")
+ serializer.startTag(Main.APP_NAMESPACE, "icon")
+ serializer.text(pos.icon.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "icon")
+ serializer.startTag(Main.APP_NAMESPACE, "label")
+ serializer.text(pos.label)
+ serializer.endTag(Main.APP_NAMESPACE, "label")
+ serializer.startTag(Main.APP_NAMESPACE, "detail")
+ serializer.text(pos.detail)
+ serializer.endTag(Main.APP_NAMESPACE, "detail")
+ serializer.startTag(Main.APP_NAMESPACE, "userChecked")
+ serializer.text(pos.userChecked.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "userChecked")
+ serializer.startTag(Main.APP_NAMESPACE, "labelColor")
+ serializer.text(pos.labelColor.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "labelColor")
+ serializer.startTag(Main.APP_NAMESPACE, "objectColor")
+ serializer.text(pos.objectColor.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "objectColor")
+ serializer.startTag(Main.APP_NAMESPACE, "paintStyle")
+ serializer.text(pos.paintStyle)
+ serializer.endTag(Main.APP_NAMESPACE, "paintStyle")
+ serializer.startTag(Main.APP_NAMESPACE, "strokeWidth")
+ serializer.text(pos.getstrokeWidth().toString())
+ serializer.endTag(Main.APP_NAMESPACE, "strokeWidth")
+ serializer.startTag(Main.APP_NAMESPACE, "fontSize")
+ serializer.text(pos.fontSize.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "fontSize")
+ serializer.endTag(Main.APP_NAMESPACE, "object")
+ }
+
+ // 接続線の出力 (保持しているものはすべて表示する)
+ val lineKeys = objectHolder.connectLineHolder.lineKeys
+ while (lineKeys.hasMoreElements())
+ {
+ val key = lineKeys.nextElement()
+ val line = objectHolder.connectLineHolder.getLine(key)
+ serializer.startTag(Main.APP_NAMESPACE, "line")
+ serializer.attribute(Main.APP_NAMESPACE, "key", key.toString())
+ serializer.startTag(Main.APP_NAMESPACE, "fromObjectKey")
+ serializer.text(line.fromObjectKey.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "fromObjectKey")
+ serializer.startTag(Main.APP_NAMESPACE, "toObjectKey")
+ serializer.text(line.toObjectKey.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "toObjectKey")
+ serializer.startTag(Main.APP_NAMESPACE, "lineStyle")
+ serializer.text(line.lineStyle.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "lineStyle")
+ serializer.startTag(Main.APP_NAMESPACE, "lineShape")
+ serializer.text(line.lineShape.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "lineShape")
+ serializer.startTag(Main.APP_NAMESPACE, "lineThickness")
+ serializer.text(line.lineThickness.toString())
+ serializer.endTag(Main.APP_NAMESPACE, "lineThickness")
+ serializer.endTag(Main.APP_NAMESPACE, "line")
+ }
+
+ serializer.endTag(Main.APP_NAMESPACE, "memoma")
+ serializer.endDocument()
+ writer.flush()
+ writer.close()
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+ {
+ values.put(MediaStore.Downloads.IS_PENDING, false)
+ resolver.update(documentUri, values, null, null)
+ }
+ }
+ catch (e: Exception)
+ {
+ resultMessage = " ERR " + e.message
+ Log.v(TAG, resultMessage)
+ e.printStackTrace()
+ }
+ return resultMessage
+ }
+
+ companion object {
+ private val TAG = ExtensionXmlExport::class.java.simpleName
+ }
+}
--- /dev/null
+package jp.sourceforge.gokigen.memoma.extension
+
+import android.content.Context
+import android.graphics.RectF
+import android.net.Uri
+import android.util.Log
+import android.util.Xml
+import jp.sourceforge.gokigen.memoma.Main
+import jp.sourceforge.gokigen.memoma.holders.MeMoMaObjectHolder
+import jp.sourceforge.gokigen.memoma.holders.ObjectConnector
+import jp.sourceforge.gokigen.memoma.holders.PositionObject
+import org.xmlpull.v1.XmlPullParser
+import java.io.BufferedReader
+import java.io.InputStream
+import java.io.InputStreamReader
+
+class ExtensionXmlImport(private val context: Context, private val objectHolder: MeMoMaObjectHolder, private val importUri: Uri)
+{
+ private var position: PositionObject? = null
+ private var line: ObjectConnector? = null
+ private var backgroundUri = ""
+ private var userCheckboxString = ""
+
+ fun importFromXmlFile() : String
+ {
+ var resultMessage = ""
+ val parser = Xml.newPullParser()
+ try
+ {
+ val inputStream: InputStream? = context.contentResolver.openInputStream(importUri)
+ val reader = BufferedReader(InputStreamReader(inputStream))
+ parser.setInput(reader)
+ var eventType = parser.eventType
+
+ // オブジェクトとラインをすべてクリアする
+ objectHolder.removeAllPositions()
+ val lineHolder = objectHolder.connectLineHolder ?: return "ERR>lineHolder is null."
+ lineHolder.removeAllLines()
+ while (eventType != XmlPullParser.END_DOCUMENT)
+ {
+ when (eventType)
+ {
+ XmlPullParser.START_DOCUMENT -> {}
+ XmlPullParser.START_TAG -> parseStartTag(parser.name, parser, objectHolder)
+ XmlPullParser.END_TAG -> parseEndTag(parser.name)
+ else -> {}
+ }
+ eventType = parser.next()
+ }
+ reader.close()
+ }
+ catch (e: Exception)
+ {
+ resultMessage = " ERR " + e.message
+ Log.v(TAG, resultMessage)
+ e.printStackTrace()
+ }
+ return resultMessage
+ }
+
+ private fun parseStartTag(
+ name: String,
+ parser: XmlPullParser,
+ objectHolder: MeMoMaObjectHolder?
+ )
+ {
+ try
+ {
+ if (name.equals("top", ignoreCase = true) && position != null) {
+ position?.setRectTop(parser.nextText().toFloat())
+ } else if (name.equals("bottom", ignoreCase = true) && position != null) {
+ position?.setRectBottom(parser.nextText().toFloat())
+ } else if (name.equals("left", ignoreCase = true) && position != null) {
+ position?.setRectLeft(parser.nextText().toFloat())
+ } else if (name.equals("right", ignoreCase = true) && position != null) {
+ position?.setRectRight(parser.nextText().toFloat())
+ } else if (name.equals("drawStyle", ignoreCase = true) && position != null) {
+ position?.setDrawStyle(parser.nextText().toInt())
+ } else if (name.equals("icon", ignoreCase = true) && position != null) {
+ position?.setIcon(parser.nextText().toInt())
+ } else if (name.equals("label", ignoreCase = true) && position != null) {
+ position?.setLabel(parser.nextText())
+ } else if (name.equals("detail", ignoreCase = true) && position != null) {
+ position?.setDetail(parser.nextText())
+ } else if (name.equals("userChecked", ignoreCase = true) && position != null) {
+ val parseData = parser.nextText()
+ position?.setUserChecked(parseData.equals("true", ignoreCase = true))
+ } else if (name.equals("labelColor", ignoreCase = true) && position != null) {
+ position?.setLabelColor(parser.nextText().toInt())
+ } else if (name.equals("objectColor", ignoreCase = true) && position != null) {
+ position?.setObjectColor(parser.nextText().toInt())
+ } else if (name.equals("paintStyle", ignoreCase = true) && position != null) {
+ position?.setPaintStyle(parser.nextText())
+ } else if (name.equals("strokeWidth", ignoreCase = true) && position != null) {
+ position?.setStrokeWidth(parser.nextText().toFloat())
+ } else if (name.equals("fontSize", ignoreCase = true) && position != null) {
+ position?.setFontSize(parser.nextText().toFloat())
+ } else if (name.equals("fromObjectKey", ignoreCase = true) && line != null) {
+ line?.setFromObjectKey(parser.nextText().toInt())
+ } else if (name.equals("toObjectKey", ignoreCase = true) && line != null) {
+ line?.setToObjectKey(parser.nextText().toInt())
+ } else if (name.equals("lineStyle", ignoreCase = true) && line != null) {
+ line?.setLineStyle(parser.nextText().toInt())
+ } else if (name.equals("lineShape", ignoreCase = true) && line != null) {
+ line?.setLineShape(parser.nextText().toInt())
+ } else if (name.equals("lineThickness", ignoreCase = true) && line != null) {
+ line?.setLineThickness(parser.nextText().toInt())
+ } else if (name.equals("title", ignoreCase = true) && objectHolder != null) {
+ objectHolder.dataTitle = parser.nextText()
+ } else if (name.equals("background", ignoreCase = true) && objectHolder != null) {
+ objectHolder.background = parser.nextText()
+ } else if (name.equals("backgroundUri", ignoreCase = true) && objectHolder != null) {
+ backgroundUri = parser.nextText()
+ } else if (name.equals(
+ "userCheckboxString",
+ ignoreCase = true
+ ) && objectHolder != null
+ ) {
+ userCheckboxString = parser.nextText()
+ } else if (name.equals("objserial", ignoreCase = true) && objectHolder != null) {
+ objectHolder.serialNumber = parser.nextText().toInt()
+ //Log.v(Main.APP_IDENTIFIER, "objSerial : " + objectHolder.getSerialNumber());
+ } else if (name.equals("lineserial", ignoreCase = true) && objectHolder != null) {
+ objectHolder.connectLineHolder.serialNumber = parser.nextText().toInt()
+ //Log.v(Main.APP_IDENTIFIER, "lineSerial : " + objectHolder.getSerialNumber());
+ } else if (name.equals("object", ignoreCase = true)) {
+ val key = parser.getAttributeValue(Main.APP_NAMESPACE, "key").toInt()
+ //Log.v(Main.APP_IDENTIFIER, "create object, key :" + key);
+ if (objectHolder != null) {
+ position = objectHolder.createPosition(key)
+ }
+ } else if (name.equals("line", ignoreCase = true)) {
+ val key = parser.getAttributeValue(Main.APP_NAMESPACE, "key").toInt()
+ //Log.v(Main.APP_IDENTIFIER, "create line, key :" + key);
+ line = null
+ if (objectHolder != null) {
+ line = objectHolder.connectLineHolder.createLine(key)
+ }
+ }
+ } catch (e: java.lang.Exception) {
+ Log.v(TAG, "ERR>parseStartTag() name:$name $e")
+ }
+ }
+ private fun parseEndTag(name: String)
+ {
+ try
+ {
+ if (name.equals("object", ignoreCase = true))
+ {
+ // 領域サイズがおかしい場合には、オブジェクトサイズを補正する (ふつーありえないはずなんだけど...)
+ val posRect: RectF? = position?.rect
+ if (posRect != null)
+ {
+ if (posRect.left > posRect.right || posRect.top > posRect.bottom)
+ {
+ Log.v(
+ TAG,
+ "RECT IS ILLEGAL. : [" + posRect.left + "," + posRect.top + "-[" + posRect.right + "," + posRect.bottom + "]"
+ )
+ position?.setRectRight(posRect.left + MeMoMaObjectHolder.OBJECTSIZE_DEFAULT_X)
+ position?.setRectBottom(posRect.top + MeMoMaObjectHolder.OBJECTSIZE_DEFAULT_Y)
+ }
+ }
+ }
+ }
+ catch (e: Exception)
+ {
+ Log.v(TAG, "ERR>parseEndTag() name:$name $e")
+ }
+ }
+
+ companion object {
+ private val TAG = ExtensionXmlImport::class.java.simpleName
+ }
+}
* ファイルのエクスポート結果を受け取る
*/
public void onCaptureLayoutExportedResult(Uri exportedUri, String detail, int id)
- {
+ {
Log.v(TAG, "MeMoMaDataInOutManager::onCaptureExportedResult() '" + objectHolder.getDataTitle() +"' : " + detail + " " + exportedUri.toString());
// エクスポートしたことを伝達する
String outputMessage = parent.getString(R.string.capture_data) + " " + objectHolder.getDataTitle() + " " + detail;
- Toast.makeText(parent, outputMessage, Toast.LENGTH_SHORT).show();
+ Toast.makeText(parent, outputMessage, Toast.LENGTH_SHORT).show();
try
{
e.printStackTrace();
}
isShareExportedData = false;
- }
+ }
/**
* エクスポートしたファイルを共有する
/**
* (CSV形式の)データを読み込んで格納する。
- *
- * @param fileName
- * @param objectHolder
- * @return
+ *
*/
private String importFromCsvFile(String fileName, MeMoMaObjectHolder objectHolder)
{
String dataLine = readRecord(buf);
while (dataLine != null)
{
- if (dataLine.startsWith(";") != true)
+ if (!dataLine.startsWith(";"))
{
// データ行だった。ログに出力する!
parseRecord(dataLine, objectHolder);
}
catch (Exception e)
{
- resultMessage = " ERR(import)>" + e.toString();
+ resultMessage = " ERR(import) " + e.getMessage();
Log.v(TAG, resultMessage);
e.printStackTrace();
}
/**
* コンストラクタ
*/
- public MeMoMaFileSavingEngine(Context context, String bgUri, String checkBoxLabel)
+ public MeMoMaFileSavingEngine(Context context, String bgUri, String checkBoxLabel)
{
this.context = context;
- // 設定データ読み出し用...。
- backgroundUri = bgUri;
- userCheckboxString = checkBoxLabel;
+ // 設定データ読み出し用...。
+ backgroundUri = bgUri;
+ userCheckboxString = checkBoxLabel;
}
/**
<string name="labelLineShapeSelection">形状</string>
<string name="Title_SelectLineShape">接続線の設定</string>
<string name="undo_operation">1つ戻す</string>
- <string name="permission_not_granted">許å\8f¯ã\81\8cå¾\97ã\82\89ã\82\8cã\81¾ã\81\9bã\82\93ã\81§ã\81\97ã\81\9fã\81®ã\81§çµ\82äº\86ã\81\97ã\81¾ã\81\99ã\80\82</string>
+ <string name="permission_not_granted">許可が得られませんでした。</string>
<string name="permission_capture_error">許可を得るタイミングでエラーが発生しました。</string>
+ <string name="import_xml">XMLファイルから取り込み…</string>
+ <string name="export_xml">XMLファイルとして出力…</string>
+ <string name="delete_content">データの削除…</string>
</resources>
<string name="undo_operation">Undo</string>
<string name="permission_not_granted">Permissions not granted by the user.</string>
<string name="permission_capture_error">Error Occurs at the request permission sequence.</string>
+ <string name="import_xml">Import from XML…</string>
+ <string name="export_xml">Export from XML…</string>
+ <string name="delete_content">Delete Content…</string>
</resources>