EBMacの開発環境を最新のXcode11に移行し、macOSもCatalinaにアップデートしたところ、Xcode11でコンパイルしたappは自動的にダークモード対応とみなされることがわかった。
せっかくなので画面の各部の色を調整し、正式にダークモード対応とした。どうでしょうか。
EBPocket for iOSもダークモード対応可能だと思うので、検討してみたい。
「ランダムハウス英語辞典Toolkit」で作成したHTMLが、EBStudio2では文字化けするという報告があった。旧EBStudioとは互換性を保っているはずなので、調査したところ、EBStudio2の新機能の「UnicodeからEPWING外字に自動登録する」が悪さをしていることがわかった。
「ランダムハウス英語辞典Toolkit」では、文字の字下げを表現するために、EPWINGの制御文字(0x1F09)を直接16進コードで表現している箇所がある。
<dd><p> [éi] a<br> Ἁ�━n.<br> Ἁ�(pl. A's or As, a's or as)<br> Ἁ�【1】英語アルファベットの第1字(母音字).<br> Ἁ�【2】A, a 字によって表される音[ei](bake),[](hat),[ɑː](father),[ɔː](small) など.<br> Ἁ�【3】A 字形の物.<br> Ἁ�【4】(印刷・スタンプ・手書きなどの)A, a 字.<br> Ἁ�【5】数学第一の既知数[量].<br> Ἁ�<b><成句></b> </p>
旧EBStudioでは、16進コードの0x1F09 0x0002 は外字として定義されていないため、そのままEPWINGに出力していたが、EBStudio2だと「Unicodeの0x1F09(Ἁ)が出現した」と解釈してしまい、そのために文字化けが生じていた。EBStudioの本来の仕様では、制御文字を直接指定したい場合のために拡張タグを用意している。
<X4081>1F09 0002</X4081>
互換性を保つために、EBStudio win版(2.0.9)およびmacOS版(2.0.5)では、「UnicodeからEPWING外字に自動登録する」機能をオプションにした。
「ランダムハウス英語辞典Toolkit」を使用する場合は、このオプションをoffで実行してほしい。
なお、「ランダムハウス英語辞典Toolkit」では「ランダムハウス英語辞典」をインストールしてから変換する前提になっているが、インストーラがWindows10では実行できない。次の手順でインストールを行わずに変換ができる。
前回EBMacをApp Store配布に切り替えると告知したが、あえなくApp Storeの審査でreject(却下)されてしまった。理由は、「EBMacというアプリケーション名称に Mac が含まれているから」。
名前が却下されてしまったのでは仕方ない。EBPocket の名称で登録してマニュアル等では "EBPocket on macOS(EBMac)"とするという方法も考えられるが、EBPocketの名称でAndroid版、iOS版、macOS版が存在することになり、問合せの時にプラットフォームを言ってもらわないと話が通じなくなる。
実は Apple notary service でAppleの認証を受ければ、これまで通り野良アプリを配付できるので、App Storeは諦めて認証を受けることにした。
App Storeで配付することを想定していたので、今回からSandBox 対応になる。これまでの辞書グループ登録は引き継げないので、もう一度辞書登録を行っていただく必要がある。
とりあえずhome pageでCatalina対応の EBMac 1.44.0 を公開した。当面はこれまで通りVectorでの配布を継続するつもりである。
NotarizeされたアプリをダウンロードしてmacOS Mojave以降で実行すると、初回のみ次のような確認メッセージが表示される。そのまま開けば次回から確認なしで実効できるので、ユーザーの負担は少ない。
EBStudio for macOSも、2020年1月までには認証を受ける必要がある。こちらも近日中に対応する予定である。
macOS 10.15 CatalinaではEBMacが実行できないという報告を受けた。当方の環境は諸般の事情でまだ 10.14 Mojave のままなので確認できていないが、考えられる理由は次の二つ。
いずれApp Store以外からのアプリケーションのインストールが禁止される可能性もあるので、この機会にEBMac をApp Storeに登録する方向で考えている。というのは、2016年頃から、iOS Developer Program と Mac Developer Programが統合されてApple Developer Program になったので、iOSの開発者もMac のアプリケーションをApp Store に登録できるようになったからである。
このため、EBMacに次の改造が必要になる。
このうちSandbox対応の方が大変である。
EPWING辞書はSandboxの外にある。NSOpenPanelで開いたパス(EBMacでは辞書ファイルのパス)はアプリの起動中はアクセス権限があるが、アプリを閉じると権限が消えてしまい、次回起動時はアクセスできなくなる。そこでsecurity-scoped bookmarkにパスを保存すると、次回起動時にアクセス権限を付与することができる。この方法で実現しようと思っている。
Android M(6.0)以降では、Google翻訳をインストールすると、ブラウザ等のアプリのコンテキストメニューに"翻訳"が現れ、選択したテキストの翻訳を行うことができる。同様に、MDict等の辞書アプリをインストールすると、コンテキストメニューに辞書アプリ名が表示され、選択したテキストで辞書引きができる。
「EBPocketでは対応しないのか」と海外のユーザからの問い合わせがあったので、調査したところ簡単に対応できそうなので実装してみた。Android M以降にEBPocketをインストールすると、次のようにコンテキストメニューにEBPocketが登録される。
実装方法は下記の通り。
1.AndroidManfest.xmlにaction.PROCESS_TEXTのインテントフィルターを追加する。これで他アプリのコンテキストメニューにアプリ名が表示される。
<intent-filter> <action android:name="android.intent.action.PROCESS_TEXT" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>
2.ACTION_PROCESS_TEXTのハンドラを作成する
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 。。。 handleIntent(getIntent()); } @Override protected void onNewIntent(Intent intent) { // android:launchMode="singleTop" にした場合、 // 2回目以降のActivityの呼び出しで呼ばれる handleIntent(intent); } private void handleIntent(Intent intent) { String queryAction = intent.getAction(); if (Intent.ACTION_SEARCH.equals(queryAction)) { // handles a search query String queryString = intent.getStringExtra(SearchManager.QUERY); // queryStringで検索 } else if (Intent.ACTION_PROCESS_TEXT.equals(queryAction)) { Bundle extras = intent.getExtras(); if (extras != null) { CharSequence ext = extras.getCharSequence(Intent.EXTRA_PROCESS_TEXT); if (ext != null) { String queryString = (String) ext; // queryStringで検索 } } } }
参考になる記事:
読書尚友の最近の改良について。
読書尚友ではPDFの表示にAndroidPDFViewを使用している。このライブラリはパスワード付PDFにも対応しているので、サポートしてみた。
パスワード付のPDFを開くときに下記のようにパスワードの入力を求める。
実現方法だが、最初にpassword(null)でload()を試み、パスワード付の場合はOnErrorで定義したハンドラに飛ぶので、その中でダイアログでパスワードを入力して再度パスワードを指定してload()を行う。
private String mFilePath; private int pageNumber; private PDFView pdfView; pdfView = (PDFView)findViewById(R.id.pdfView); DoOpenPDF(null); // パスワード無しでopenを試みる private void DoOpenPDF(String _password) { File file = new File(mFilePath); if (file.exists()) { pdfView.recycle(); pdfView.fromFile(file) .enableSwipe(true) //スワイプオンオフ .swipeHorizontal(swipeHorizontal) // T:横スクロール F:縦スクロール .enableDoubletap(true) // ダブルタップでの拡大 .defaultPage(pageNumber) .onPageChange(this) .enableAnnotationRendering(false) .onLoad(this) .onError(this) .scrollHandle(new DefaultScrollHandle(this)) .password(_password) .pageFling(swipeHorizontal) .load(); } } // loadが成功した後に呼ばれる @Override public void loadComplete(int nbPages) { metaData = pdfView.getDocumentMeta(); if ( metaData != null ) { String title = metaData.getTitle(); // } } // load が失敗した場合に呼ばれる。 @Override public void onError(Throwable t) { if ( t.getMessage().equals("Password required or incorrect password.")) { final EditText editText = new EditText(this); editText.setSingleLine(); // 1行モード editText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_CLASS_TEXT); // パスワードとして入力 new AlertDialog.Builder(this) .setTitle( getString(R.string.str_incorrect_password) ) .setView(editText) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String value = editText.getText().toString(); DoOpenPDF(value); } }) .show(); } }
今後GooglePlayにアプリを提出するときにtargetSdkVersion=28以上が強制されるようになるので、今回からtargetSdkVersion=28にしたところ、Android 9(Pie)で実行するときにデフォルトではhttp:が許可されず、https:でないと通信ができないようになった。
本当はドメイン毎にhttpを許可する実装が望ましいが、安直な回避方法は、manifestに次の記述を加えるとhttp通信が許可できる。
android:usesCleartextTraffic="true"