hishidaの開発blog

EBシリーズ(EBPocket,EBWin,EBMac,EBStudio),KWIC Finder,xdoc2txt,読書尚友の開発者ブログ

読書尚友 暗号化PDF対応他

読書尚友の最近の改良について。

パスワードで保護されたPDFの表示

読書尚友ではPDFの表示にAndroidPDFViewを使用している。このライブラリはパスワード付PDFにも対応しているので、サポートしてみた。

github.com

パスワード付のPDFを開くときに下記のようにパスワードの入力を求める。

f:id:hishida:20190922084453p:plain

実現方法だが、最初に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();
    }
}


作品リストの絞り込み検索、高速スクロール他

  1. 作品リストに表示される件数が多い場合に目的の作品を見つけるのが困難なので、作品リストの上部に絞り込み検索の窓をもうけた。
  2. ListViewにsetFastScrollEnabled(true)を適用して右端に高速スクロールのためのつまみが表示されるようにした。ただし項目の右側のボタン(縦の…)が押しにくくなるので、右端からボタンまでの距離を多めにとって調整した。
  3. これまでは、「ダウンロードした作品にダウンロード済みのマークを表示」していたが、本棚と表示方法を統一し、「未ダウンロードの作品に雲マークを表示する」ように変更した。

f:id:hishida:20190922084503p:plain

Android 9 でのhttp通信に対応

今後GooglePlayにアプリを提出するときにtargetSdkVersion=28以上が強制されるようになるので、今回からtargetSdkVersion=28にしたところ、Android 9(Pie)で実行するときにデフォルトではhttp:が許可されず、https:でないと通信ができないようになった。

本当はドメイン毎にhttpを許可する実装が望ましいが、安直な回避方法は、manifestに次の記述を加えるとhttp通信が許可できる。

android:usesCleartextTraffic="true"

 

 

EBPocket for Android 夜間モード対応

Zenfone Max pro M2 をファームアップAndroid 9(Pie)にバージョンアップしたところ、開発者向けオプションの中にNight Modeの設定があることに気がついた。

f:id:hishida:20190903182011p:plain

「自動」に設定してみると夕暮れ時頃にNight Modeに変わる。読書尚友は既に夜間モード対応を入れていたが、EBPocketはまだだったので、この機会に夜間モード対応にしてみた。

ebstudio.hatenablog.com

夜間モードのEBPocket。いい感じですね。

f:id:hishida:20190903182028p:plain

iOS13でもダークモードがサポートされるという話なので、そろそろEBPocket iPhone版も重い腰を上げて対応しないといけないかも。

EBPocket for Android 最近の更新

最近のEBPocket for Androidの更新内容についてご紹介したい。

EPWING系辞書のブックマーク、履歴対応

これまで内部的な事情でブックマークや履歴はEPWING系辞書(電子ブックEB/EBXAやロゴヴィスタを含む)しか対応していなかったが、今回の改良で、非EPWING系辞書(StarDict、MDict、PDIC、ユーザ辞書)もブックマーク、履歴に登録できるようになった。

アダプティブアイコン対応

最近スマートフォンAsus Zenfone Max Pro M2(Android8.1)に変えたところ、EBPocketのアイコンが小さく表示されることに気がついた。どうもtargetSDKを26(Android8.0)以上にしていると、アダプティブアイコンへの対応が必須になるらしい。

アダプティブアイコンはアイコンのバックグラウンドとフォアグラウドを別々に指定し、丸や楕円やスクエアなどシステム側でトリミングして表示する仕組みである。バックグラウンドは画像でもいいし単色指定でもいい。

Android StudioのImage Assetを使うとオリジナルの512x512の図形があれば、自動的にAndroid7.1用の丸アイコンと、8.0用のアダプティブアイコンを作成してくれる。

f:id:hishida:20190616173929p:plain

辞書検索パスの指定でSDカードのアイコンを表示

SDカードに入れた辞書の設定の仕方がわからないという声をずいぶんいただくので、辞書検索パスの設定画面に内蔵ストレージのホームと外部SDのアイコンを追加した。これで指定がしやすくなったと思う。 

f:id:hishida:20190616173913p:plain




 

EBWin4.7 公開!~ドッキングウインドウ、単語帳~

予告していたEBWin4のドッキングウインドウ対応が実用レベルに達したので、先行公開することにした。

EB series support page

 合わせて以前から気になっていた問題点にいろいろ対応したので、過去最大のアップデートになった。

ドッキングウインドウ、タブモード

検索結果、ブックマーク、本文などのウインドウを、画面の上下左右に自由にドッキングできる。
タブモードでは辞書毎に本文ウインドウが開くので、タブで切り替えて参照したり、タイル上に配置して、辞書毎に語釈の違いを読み比べたりできる。

押しピンを外すと自動開閉モードになる。下のスクリーンショットでは、右端にドッキングした複合検索がAutoHide状態になっている。「複合検索」のタブをクリックするとパネルが開く。

f:id:hishida:20190519083645p:plain

EPWING系辞書(PDIC,StarDict,MDict,ユーザ辞書)のブックマーク対応

内部的な事情で、これまでのEBシリーズではブックマークに登録できる辞書はEPWING系だけで、PDIC、StarDict、MDict、ユーザ辞書をブックマークに登録できなかった。今回やっと全ての辞書の種類でブックマークに登録できるようになった。
EBWin4以外のプラットフォームの対応だが、ソースの共通化が進んでいるEBPocket for Android はすぐに対応できると思う。Mac版とiOS版は対応に時間がかかる見込みである。

単語帳

今回のもう一つの目玉だが、外部の単語帳を読み込んで検索できるようになった。

f:id:hishida:20190528181441p:plain

単語帳に読み込んだ語を選択すると、現在選択された辞書で検索を行う(串刺し検索も可)。
見本の単語帳として、次のテキストデータを配布ファイルに同梱している。

www.newgeneralservicelist.org


本当は単語の学習にはAnkiなどのほうが向いていると思うが、辞書を引いてみたい場合もあると思うので、実験的に導入してみた。

 

EBWin4 のドッキングウインドウ化を実験中

KWIC Finderのリニューアルで導入したドッキングウィンドウがなかなか便利なので、EBWin4にも導入してみることにした。
C#Windows Form のドッキングウィンドウのライブラリには、DockPanel Suiteを使用している。

DockPanel Suite - The .NET WinForms Docking Library

ドッキングウィンドウ化したEBWin4の画面例。

f:id:hishida:20190519083645p:plain

検索結果、ブックマーク、検索履歴、複合検索パネル、辞書本文を独自のペインとして画面上の好きなところに配置できる。
辞書本文はタブ形式で表示することもできるし、タイル形式で配置することもできる。

次の画面では、辞書本文はタブ形式表示で、複合検索パネルと検索結果を並べて表示している例。

f:id:hishida:20190519083709p:plain

手元ではほぼ動いているが、大型のアップデートなのでまだ一ヶ月くらいはテスト期間をおいてから公開したい。

こういう便利なライブラリが簡単に見つかるのがC#のいいところだ。EBMacも同様の複数辞書表示をしてほしいという要望が過去にあったが、Mac版の実装はたぶん無理だと思う。

Android 1.6用のEBPocket for Androidの公開

IS01やIS02などの古いAndroid1.6用のEBPocketがGoogle Playから落とせなくなっているという報告をいただいたので、Android1.6用の最終のEBPocket 1.15.0を公開することにしました。

下記HPからダウンロードし、実機に転送してファイルブラウザでタップするとインストールされます。

EBPocket for Android

読書尚友 夜間モード

macOS Mojave でダークモードが搭載され、他OSでも流行りそうな気配である。

AndroidではAndroid N Developer Preview(初期版)では夜間モードがあったが、実際の製品では搭載が見送られた。だがスマートフォンの場合はバッテリの持ちが長くなるメリットがあるため、将来的に標準搭載されると思う。Twitterのようにアプリレベルで夜間モードを搭載しているものもある。

実はSupport Library の AppCompat 23.2.0 以降、DayNight テーマが導入されており、アプリレベルでの実装が簡単になった

qiita.com

ということで読書尚友にも夜間モードを実装してみた。

f:id:hishida:20190206163531j:plain

f:id:hishida:20190206163543j:plain

f:id:hishida:20190206163555j:plain

f:id:hishida:20190206163606j:plain

読書画面の背景色はこれまでもカスタマイズできたが、すべての画面のパーツの背景色をダークモードに切り替えられるのがミソである。

 

実装方法

ActivityのテーマのベースにTheme.AppCompat.DayNightを使用します。

styles.xml

<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>

<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.ActionBar">
<item name="windowActionBar">true</item>
<item name="windowNoTitle">false</item>
</style>

</resources>

 

 

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="textColorPrimary">#FFFFFF</color>

</resources>

 

 

AndroidManifest.xml

<activity android:name="MainActivity"

android:label="@string/app_name"              android:theme="@style/AppTheme.ActionBar" >

</activity>

 

 アプリでは、OnCreateの先頭で夜間モードを設定します。

MainActivity.java

public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {

if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {  AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
}
super.onCreate(savedInstanceState);
.....

 

 

AppCompatDelegate.MODE_NIGHT_AUTO 自動切替
AppCompatDelegate.MODE_NIGHT_NO 夜間モードオフ
AppCompatDelegate.MODE_NIGHT_YES 夜間モードオン
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM システムに依存

 自動切替を実験したところ、22:00に夜間モードに切り替わるようだ。