KDP(電子出版)のメモ 急急如律令

Amazon Kindleダイレクト・パブリッシングでの電子出版や電子書籍の作成販売について、文章やイラストの作成や編集方法について書いています。

iniからandroid向けのpreference画面を作る

PC版ではiniに設定ファイルを保存していたのをAndroidで使われるpreferenceから設定を書き換える。

developer.android.com

あなた:

次のiniからandroid向けのpreference画面を作って

#AozoraEpub3 Parameters
#Thu Oct 10 00:33:19 GMT+09:00 2024
AutoFileName=1
AutoMargin=
AutoMarginLimitH=15
AutoMarginLimitV=15
AutoMarginNombre=0
AutoMarginNombreSize=3.0
AutoMarginPadding=1.0
AutoMarginWhiteLevel=80
AutoYoko=1
AutoYokoEQ1=
AutoYokoNum1=
AutoYokoNum3=
BodyMargin=0,0,0,0
BodyMarginUnit=0
BoldUseGothic=
CachePath=.cache
ChapterExclude=1
ChapterH=1
ChapterH1=1
ChapterH2=1
ChapterH3=1
ChapterName=1
ChapterNumOnly=
ChapterNumParen=
ChapterNumParenTitle=
ChapterNumTitle=
ChapterPattern=
ChapterPatternText=
ChapterSection=1
ChapterUseNextLine=
ChkConfirm=1
ChukiRuby=0
CommentConvert=
CommentPrint=
Cover=
CoverH=0
CoverHistory=
CoverPage=1
CoverPageToc=
CoverW=0
DakutenType=2
DispH=2560
DispW=1600
DividerLocation=230
DstPath=C\:\\Users\\Owner\\Downloads
DstPathList=C\:\\Users\\Owner\\Downloads
EncType=0
Ext=.mobi+.epub
FitImage=
FontSize=100
ForceIndent=
Gamma=
GammaValue=1.0
GothicUseBold=
ImageFloat=
ImageFloatBlock=
ImageFloatH=400
ImageFloatPage=
ImageFloatType=0
ImageFloatW=600
ImageScale=1.0
ImageScaleChecked=
ImageSizeType=1
IvsBMP=
IvsSSP=
JpegQuality=85
LangType=ja
LastDir=
LineHeight=1.5
MarkId=
MaxChapterNameLength=64
MaxCoverLine=
MaxEmptyLine=0
NavNest=1
NcxNest=1
NoIllust=
OverWrite=1
PageBreak=
PageBreakChapter=
PageBreakChapterSize=200
PageBreakEmpty=
PageBreakEmptyLine=2
PageBreakEmptySize=300
PageBreakSize=400
PageMargin=0,0,0,0
PageMarginUnit=0
PosX=626.0
PosY=507.0
ProfileFileName=20230320-214852.ini
ProfileList=20230320-214852.ini
PubFirst=
RemoveEmptyLine=0
ReplaceCover=
ResizeH=
ResizeNumH=2048
ResizeNumW=2048
ResizeW=
RotateImage=0
SameLineChapter=
SamePath=
SinglePageSizeH=300
SinglePageSizeW=200
SinglePageWidth=300
SizeH=458.0
SizeW=540.0
SpaceHyphenation=1
SvgImage=
TitlePage=1
TitlePageWrite=1
TitleToc=1
TitleType=0
TocPage=
TocVertical=1
UseFileName=
UserAgent=Chrome
Vertical=1
WebBeforeChapter=
WebBeforeChapterCount=1
WebConvertUpdated=
WebInterval=0.5
WebModifiedExpire=24
WebModifiedOnly=
WebModifiedTail=
jCheckWebLageImage=

ChatGPT:

この .ini ファイルに基づいて、Android 向けの PreferenceScreen を作成します。 Android の Preference 画面は res/xml/preferences.xml に定義し、PreferenceFragmentCompat を使って表示するのが一般的です。

以下は、ini の設定を反映した PreferenceScreen の XML です。

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- ファイル関連 -->
    <SwitchPreferenceCompat
        android:key="AutoFileName"
        android:title="自動ファイル名"
        android:defaultValue="true" />

    <EditTextPreference
        android:key="DstPath"
        android:title="保存先"
        android:dialogTitle="保存先を入力"
        android:defaultValue="C:\\Users\\Owner\\Downloads" />

    <ListPreference
        android:key="Ext"
        android:title="出力フォーマット"
        android:dialogTitle="フォーマットを選択"
        android:entries="@array/ext_options"
        android:entryValues="@array/ext_values"
        android:defaultValue=".mobi+.epub" />

    <!-- 画像関連 -->
    <SwitchPreferenceCompat
        android:key="FitImage"
        android:title="画像をページにフィット" />

    <SeekBarPreference
        android:key="JpegQuality"
        android:title="JPEG品質"
        android:max="100"
        android:min="0"
        android:defaultValue="85" />

    <!-- 文字・レイアウト関連 -->
    <SeekBarPreference
        android:key="FontSize"
        android:title="フォントサイズ"
        android:max="200"
        android:min="50"
        android:defaultValue="100" />

    <SwitchPreferenceCompat
        android:key="Vertical"
        android:title="縦書き" />

    <SeekBarPreference
        android:key="LineHeight"
        android:title="行間"
        android:max="3"
        android:min="1"
        android:defaultValue="1.5"
        android:float="true" />

    <!-- その他の設定 -->
    <SwitchPreferenceCompat
        android:key="OverWrite"
        android:title="ファイルを上書き" 
        android:defaultValue="true" />

</PreferenceScreen>

res/values/arrays.xml を作成し、リスト選択肢を定義します。

<resources>
    <string-array name="ext_options">
        <item>MOBI + EPUB</item>
        <item>EPUBのみ</item>
        <item>MOBIのみ</item>
    </string-array>

    <string-array name="ext_values">
        <item>.mobi+.epub</item>
        <item>.epub</item>
        <item>.mobi</item>
    </string-array>
</resources>

PreferenceFragmentCompat を使って設定画面を作ります。

class SettingsFragment : PreferenceFragmentCompat() {
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences, rootKey)
    }
}

SettingsFragment を MainActivity に表示する。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        supportFragmentManager.beginTransaction()
            .replace(android.R.id.content, SettingsFragment())
            .commit()
    }
}

この PreferenceScreen は .ini ファイルの主要な設定項目を Android の設定画面に落とし込んだものです。 細かい調整は、必要に応じて SeekBarPreference の max 値や ListPreference の選択肢を変更してください。

あなた:

javaでandroid向けのpreferenceの作り方

ChatGPT:

Java で Android 向けの PreferenceScreen を作成する方法を解説します。 PreferenceFragmentCompat を使って、設定画面を実装します。

まず、設定画面のレイアウトを定義します。 res/xml/preferences.xml に次の内容を追加してください。

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- ファイル関連 -->
    <SwitchPreferenceCompat
        android:key="AutoFileName"
        android:title="自動ファイル名"
        android:defaultValue="true" />

    <EditTextPreference
        android:key="DstPath"
        android:title="保存先"
        android:dialogTitle="保存先を入力"
        android:defaultValue="C:\\Users\\Owner\\Downloads" />

    <ListPreference
        android:key="Ext"
        android:title="出力フォーマット"
        android:dialogTitle="フォーマットを選択"
        android:entries="@array/ext_options"
        android:entryValues="@array/ext_values"
        android:defaultValue=".mobi+.epub" />

    <!-- 画像関連 -->
    <SwitchPreferenceCompat
        android:key="FitImage"
        android:title="画像をページにフィット" />

    <SeekBarPreference
        android:key="JpegQuality"
        android:title="JPEG品質"
        android:max="100"
        android:min="0"
        android:defaultValue="85" />

    <!-- 文字・レイアウト関連 -->
    <SeekBarPreference
        android:key="FontSize"
        android:title="フォントサイズ"
        android:max="200"
        android:min="50"
        android:defaultValue="100" />

    <SwitchPreferenceCompat
        android:key="Vertical"
        android:title="縦書き" />

    <SeekBarPreference
        android:key="LineHeight"
        android:title="行間"
        android:max="3"
        android:min="1"
        android:defaultValue="1.5"
        android:useSimpleSummaryProvider="true" />

    <!-- その他の設定 -->
    <SwitchPreferenceCompat
        android:key="OverWrite"
        android:title="ファイルを上書き"
        android:defaultValue="true" />

</PreferenceScreen>

ListPreference で使用するリストを res/values/arrays.xml に定義します。

<resources>
    <string-array name="ext_options">
        <item>MOBI + EPUB</item>
        <item>EPUBのみ</item>
        <item>MOBIのみ</item>
    </string-array>

    <string-array name="ext_values">
        <item>.mobi+.epub</item>
        <item>.epub</item>
        <item>.mobi</item>
    </string-array>
</resources>

PreferenceFragmentCompat を拡張して設定画面を作成します。

package com.example.myapp;

import android.os.Bundle;
import androidx.preference.PreferenceFragmentCompat;

public class SettingsFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.preferences, rootKey);
    }
}

設定画面を Activity として開けるようにします。

package com.example.myapp;

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;

public class SettingsActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportFragmentManager()
            .beginTransaction()
            .replace(android.R.id.content, new SettingsFragment())
            .commit();
    }
}

アプリの設定画面を開けるように AndroidManifest.xml に SettingsActivity を登録します。

<activity android:name=".SettingsActivity"
    android:label="設定"
    android:parentActivityName=".MainActivity">
</activity>

例えば MainActivity.java にボタンを追加し、クリックすると SettingsActivity を開くようにします。

package com.example.myapp;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button settingsButton = findViewById(R.id.settings_button);
        settingsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
                startActivity(intent);
            }
        });
    }
}

res/layout/activity_main.xml にボタンを配置します。

<Button
    android:id="@+id/settings_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="設定を開く" />

アプリ内で設定値を取得するには SharedPreferences を使います。

import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;

// 設定値を取得する例
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean autoFileName = prefs.getBoolean("AutoFileName", true);
String dstPath = prefs.getString("DstPath", "C:\\Users\\Owner\\Downloads");
int fontSize = prefs.getInt("FontSize", 100);
  • XML で PreferenceScreen を定義
  • SettingsFragment で PreferenceFragmentCompat を継承
  • SettingsActivity で設定画面を表示
  • MainActivity のボタンから SettingsActivity を開く
  • SharedPreferences で設定値を取得

XML で PreferenceScreen を定義

SettingsFragment で PreferenceFragmentCompat を継承

SettingsActivity で設定画面を表示

MainActivity のボタンから SettingsActivity を開く

SharedPreferences で設定値を取得

この方法で、Android の設定画面を Java で実装できます! 🚀

あなた:

次のコードをandroidのpreferenceに書き換えて

/** propsの値をアプレットに設定 */
private void loadProperties(Properties props)
{
    boolean selected;

    //表題
    if(props.getProperty("TitleType")!=null){
    jComboTitle.setSelectedIndex(Integer.parseInt(props.getProperty("TitleType")));};
    setPropsSelected(jCheckPubFirst, props, "PubFirst");
    setPropsSelected(jCheckUseFileName, props, "UseFileName");
    //表紙
    if (props.getProperty("Cover")==null|| props.getProperty("Cover").isEmpty()) jComboCover.setSelectedIndex(0);
    else jComboCover.setSelectedItem(props.getProperty("Cover"));
    //表紙履歴
    setPropsSelected(jCheckCoverHistory, props, "CoverHistory");
    //有効行数
    setPropsIntText(jTextMaxCoverLine, props, "MaxCoverLine");

    setPropsSelected(jCheckCoverPage, props, "CoverPage");
    //表題ページ
    setPropsSelected(jCheckTitlePage, props, "TitlePageWrite");
    String propValue = props.getProperty("TitlePage");
    if (propValue != null) {
        jRadioTitleNormal.setSelected(Integer.toString(BookInfo.TITLE_NORMAL).equals(propValue));
        jRadioTitleMiddle.setSelected(Integer.toString(BookInfo.TITLE_MIDDLE).equals(propValue));
        jRadioTitleHorizontal.setSelected(Integer.toString(BookInfo.TITLE_HORIZONTAL).equals(propValue));
    }

    setPropsSelected(jCheckTocPage, props, "TocPage");
    selected = setPropsSelected(jRadioTocV, props, "TocVertical");
    jRadioTocH.setSelected(!selected);
    //出力ファイル設定
    //拡張子
    if (props.getProperty("Ext") != null && !props.getProperty("Ext").isEmpty())
        jComboExt.setSelectedItem(props.getProperty("Ext"));
    //出力ファイル名設定
    setPropsSelected(jCheckAutoFileName, props, "AutoFileName");
    //ファイルの上書き許可
    setPropsSelected(jCheckOverWrite, props, "OverWrite");
    //栞用ID出力
    setPropsSelected(jCheckMarkId, props, "MarkId");
    //4バイト文字を変換する
    //setPropsSelected(jCheckGaiji32, props, "Gaiji32");
    //縦書き横書き
    selected= setPropsSelected(jRadioVertical, props, "Vertical");
    jRadioHorizontal.setSelected(!selected);
    //入力文字コード
    if(props.getProperty("EncType")!=null){
    jComboEncType.setSelectedIndex(Integer.parseInt(props.getProperty("EncType"))); } 

    //言語設定
    if (props.getProperty("LangType") != null && !props.getProperty("LangType").isEmpty())
        jComboLangType.setSelectedItem(props.getProperty("LangType"));

    ////////////////////////////////////////////////////////////////
    //画像設定
    setPropsSelected(jCheckNoIllust, props, "NoIllust");
    //画面サイズ
    setPropsIntText(jTextDispW, props, "DispW");
    setPropsIntText(jTextDispH, props, "DispH");
    //表紙サイズ
    setPropsIntText(jTextCoverW, props, "CoverW");
    setPropsIntText(jTextCoverH, props, "CoverH");
    //画像単ページ化
    setPropsIntText(jTextSinglePageSizeW, props, "SinglePageSizeW");
    setPropsIntText(jTextSinglePageSizeH, props, "SinglePageSizeH");
    //横のみ
    setPropsIntText(jTextSinglePageWidth, props, "SinglePageWidth");
    //サイズ指定
    propValue = props.getProperty("ImageSizeType");
    if (propValue != null) {
        jRadioImageSizeType1.setSelected(Integer.toString(SectionInfo.IMAGE_SIZE_TYPE_AUTO).equals(propValue));
        jRadioImageSizeType3.setSelected(Integer.toString(SectionInfo.IMAGE_SIZE_TYPE_ASPECT).equals(propValue));
    }
    //拡大しない
    setPropsSelected(jCheckFitImage, props, "FitImage");
    //SVG画像タグ出力
    setPropsSelected(jCheckSvgImage, props, "SvgImage");
    if(props.getProperty("RotateImage")!=null){ jComboRotateImage.setSelectedIndex(Integer.parseInt(props.getProperty("RotateImage"))); }
    //画像倍率
    setPropsSelected(jCheckImageScale, props, "ImageScaleChecked", false);
    setPropsFloatText(jTextImageScale, props, "ImageScale");
    //画像回り込み
    setPropsSelected(jCheckImageFloat, props, "ImageFloat");
    setPropsIntText(jTextImageFloatW, props, "ImageFloatW");
    setPropsIntText(jTextImageFloatH, props, "ImageFloatH");
    if(props.getProperty("ImageFloatType")!=null){ jComboImageFloatType.setSelectedIndex(Integer.parseInt(props.getProperty("ImageFloatType"))); }
    //画像縮小指定
    setPropsSelected(jCheckResizeW, props, "ResizeW");
    setPropsIntText(jTextResizeNumW, props, "ResizeNumW");
    setPropsSelected(jCheckResizeH, props, "ResizeH");
    setPropsIntText(jTextResizeNumH, props, "ResizeNumH");
    //Float表示 (デフォルトOFF)
    setPropsSelected(jCheckImageFloatPage, props, "ImageFloatPage", false);
    setPropsSelected(jCheckImageFloatBlock, props, "ImageFloatBlock", false);
    //Jpeg圧縮率
    setPropsIntText(jTextJpegQuality, props, "JpegQuality");
    //ガンマ補正
    setPropsSelected(jCheckGamma, props, "Gamma");
    setPropsFloatText(jTextGammaValue, props, "GammaValue");
    //余白除去
    setPropsSelected(jCheckAutoMargin, props, "AutoMargin");
    setPropsIntText(jTextAutoMarginLimitH, props, "AutoMarginLimitH");
    setPropsIntText(jTextAutoMarginLimitV, props, "AutoMarginLimitV");
    setPropsIntText(jTextAutoMarginWhiteLevel, props, "AutoMarginWhiteLevel");
    setPropsFloatText(jTextAutoMarginPadding, props, "AutoMarginPadding");
    if(props.getProperty("AutoMarginNombre")!=null){ jComboAutoMarginNombre.setSelectedIndex(Integer.parseInt(props.getProperty("AutoMarginNombre"))); } 
    setPropsFloatText(jTextAutoMarginNombreSize, props, "AutoMarginNombreSize");

    ////////////////////////////////////////////////////////////////
    //詳細設定
    propValue = props.getProperty("SpaceHyphenation");
    if (propValue != null) {
        jRadioSpaceHyp1.setSelected("1".equals(propValue));
        jRadioSpaceHyp2.setSelected("2".equals(propValue));
        jRadioSpaceHyp0.setSelected("0".equals(propValue));
    }
    //注記のルビ表示
    propValue = props.getProperty("ChukiRuby");
    if (propValue != null) {
        jRadioChukiRuby0.setSelected("0".equals(propValue));
        jRadioChukiRuby1.setSelected("1".equals(propValue));
        jRadioChukiRuby2.setSelected("2".equals(propValue));
    }
    //自動縦中横
    //半角2文字縦書き
    setPropsSelected(jCheckAutoYoko, props, "AutoYoko");
    //半角数字1文字縦書き
    setPropsSelected(jCheckAutoYokoNum1, props, "AutoYokoNum1");
    //半角数字3文字縦書き
    setPropsSelected(jCheckAutoYokoNum3, props, "AutoYokoNum3");
    //!? 1文字
    setPropsSelected(jCheckAutoEQ1, props, "AutoYokoEQ1");
    //コメント出力
    setPropsSelected(jCheckCommentPrint, props, "CommentPrint");
    setPropsSelected(jCheckCommentConvert, props, "CommentConvert");
    //空行除去
    if(props.getProperty("RemoveEmptyLine")!=null){ jComboxRemoveEmptyLine.setSelectedIndex(Integer.parseInt(props.getProperty("RemoveEmptyLine"))); }
    propValue = props.getProperty("MaxEmptyLine");
    if(propValue!=null){jComboxMaxEmptyLine.setSelectedIndex(Integer.parseInt(propValue)); } 
    //行頭字下げ追加
    setPropsSelected(jCheckForceIndent, props, "ForceIndent");
    //強制改ページ
    setPropsSelected(jCheckPageBreak, props, "PageBreak");
    if(props.getProperty("PageBreakSize")!=null){ jTextPageBreakSize.setText(Integer.toString(Integer.parseInt(props.getProperty("PageBreakSize")))); }
    setPropsSelected(jCheckPageBreakEmpty, props, "PageBreakEmpty");
    propValue = props.getProperty("PageBreakEmptyLine");
    if (propValue != null) jComboxPageBreakEmptyLine.setSelectedItem(propValue);
    setPropsIntText(jTextPageBreakEmptySize, props, "PageBreakEmptySize");
    setPropsSelected(jCheckPageBreakChapter, props, "PageBreakChapter");
    setPropsIntText(jTextPageBreakChapterSize, props, "PageBreakChapterSize");

    ////////////////////////////////////////////////////////////////
    //目次設定
    //最大文字数
    setPropsIntText(jTextMaxChapterNameLength, props, "MaxChapterNameLength");
    //表紙
    setPropsSelected(jCheckCoverPageToc, props, "CoverPageToc");
    setPropsSelected(jCheckTitleToc, props, "TitleToc");
    setPropsSelected(jCheckChapterUseNextLine, props, "ChapterUseNextLine");
    setPropsSelected(jCheckChapterExclude, props, "ChapterExclude");
    //目次階層化
    setPropsSelected(jCheckNavNest, props, "NavNest");
    setPropsSelected(jCheckNcxNest, props, "NcxNest");
    //改ページ後を目次に追加
    setPropsSelected(jCheckChapterSection, props, "ChapterSection");
    //見出し注記
    setPropsSelected(jCheckChapterH, props, "ChapterH");
    setPropsSelected(jCheckChapterH1, props, "ChapterH1");
    setPropsSelected(jCheckChapterH2, props, "ChapterH2");
    setPropsSelected(jCheckChapterH3, props, "ChapterH3");
    setPropsSelected(jCheckSameLineChapter, props, "SameLineChapter");
    //章番号、数字、パターン
    setPropsSelected(jCheckChapterName, props, "ChapterName");
    setPropsSelected(jCheckChapterNumOnly, props, "ChapterNumOnly");
    setPropsSelected(jCheckChapterNumTitle, props, "ChapterNumTitle");
    setPropsSelected(jCheckChapterNumParen, props, "ChapterNumParen");
    setPropsSelected(jCheckChapterNumParenTitle, props, "ChapterNumParenTitle");
    setPropsSelected(jCheckChapterPattern, props, "ChapterPattern");
    if (props.containsKey("ChapterPatternText")) jComboChapterPattern.setSelectedItem(props.getProperty("ChapterPatternText"));

    ////////////////////////////////////////////////////////////////
    //スタイル
    propValue = props.getProperty("PageMargin");
    if (propValue != null) {
        String[] pageMargins = propValue.split(",");
        for (int i=0; i<pageMargins.length; i++) jTextPageMargins[i].setText(pageMargins[i]);
    }
    propValue = props.getProperty("PageMarginUnit");
    if (propValue != null) {
        jRadioPageMarginUnit0.setSelected("0".equals(propValue));
        jRadioPageMarginUnit1.setSelected("1".equals(propValue));
        //jRadioPageMarginUnit2.setSelected("2".equals(propValue));
    }
    propValue = props.getProperty("BodyMargin");
    if (propValue != null) {
        String[] bodyMargins = propValue.split(",");
        for (int i=0; i<bodyMargins.length; i++) jTextBodyMargins[i].setText(bodyMargins[i]);
    }
    propValue = props.getProperty("BodyMarginUnit");
    if (propValue != null) {
        jRadioBodyMarginUnit0.setSelected("0".equals(propValue));
        jRadioBodyMarginUnit1.setSelected("1".equals(propValue));
        //jRadioBodyMarginUnit2.setSelected("2".equals(propValue));
    }
    propValue = props.getProperty("LineHeight");
    if (propValue != null && !propValue.isEmpty()) jComboLineHeight.setSelectedItem(propValue);
    propValue = props.getProperty("FontSize");
    if (propValue != null && !propValue.isEmpty()) jComboFontSize.setSelectedItem(propValue);
    setPropsSelected(jCheckBoldUseGothic, props, "BoldUseGothic");
    setPropsSelected(jCheckGothicUseBold, props, "GothicUseBold");

    //文字
    propValue = props.getProperty("DakutenType");
    if (propValue != null) {
        jRadioDakutenType0.setSelected("0".equals(propValue));
        jRadioDakutenType1.setSelected("1".equals(propValue));
        jRadioDakutenType2.setSelected("2".equals(propValue));
    }
    setPropsSelected(jCheckIvsBMP, props, "IvsBMP");
    setPropsSelected(jCheckIvsSSP, props, "IvsSSP");

    ////////////////////////////////////////////////////////////////
    //Web
    setPropsFloatText(jTextWebInterval, props, "WebInterval");
    if (props.getProperty("UserAgent") != null && !props.getProperty("UserAgent").isEmpty())
        jComboUa.setSelectedItem(props.getProperty("UserAgent"));
    setPropsSelected(jCheckWebLageImage, props, "jCheckWebLageImage");
    setPropsText(jTextCachePath, props, "CachePath");
    if ("".equals(jTextCachePath.getText())) jTextCachePath.setText(".cache");
    setPropsNumberText(jTextWebModifiedExpire, props, "WebModifiedExpire");
    setPropsSelected(jCheckWebConvertUpdated, props, "WebConvertUpdated");
    setPropsSelected(jCheckWebModifiedOnly, props, "WebModifiedOnly");
    setPropsSelected(jCheckWebModifiedTail, props, "WebModifiedTail");
    setPropsSelected(jCheckWebBeforeChapter, props, "WebBeforeChapter");
    setPropsIntText(jTextWebBeforeChapterCount, props, "WebBeforeChapterCount");
}

ChatGPT:

AndroidのSharedPreferencesを使って、指定されたPropertiesの値を保存するように書き換えました。

変更点:

  • SharedPreferencesを使用して設定を保存。
  • apply()を使って非同期で保存。
  • UIコンポーネントの代わりに、SharedPreferencesのキーを使用。

SharedPreferencesを使用して設定を保存。

apply()を使って非同期で保存。

UIコンポーネントの代わりに、SharedPreferencesのキーを使用。

import android.content.Context;
import android.content.SharedPreferences;
import java.util.Properties;

public class PreferenceManager {
    private static final String PREF_NAME = "AppPreferences";
    private SharedPreferences sharedPreferences;
    private SharedPreferences.Editor editor;

    public PreferenceManager(Context context) {
        this.sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        this.editor = sharedPreferences.edit();
    }

    public void loadProperties(Properties props) {
        if (props == null) return;

        // タイトルタイプ
        if (props.getProperty("TitleType") != null) {
            editor.putInt("TitleType", Integer.parseInt(props.getProperty("TitleType")));
        }
        editor.putBoolean("PubFirst", Boolean.parseBoolean(props.getProperty("PubFirst", "false")));
        editor.putBoolean("UseFileName", Boolean.parseBoolean(props.getProperty("UseFileName", "false")));

        // 表紙
        editor.putString("Cover", props.getProperty("Cover", ""));
        editor.putBoolean("CoverHistory", Boolean.parseBoolean(props.getProperty("CoverHistory", "false")));
        editor.putInt("MaxCoverLine", parseInt(props.getProperty("MaxCoverLine")));

        // ページ設定
        editor.putBoolean("CoverPage", Boolean.parseBoolean(props.getProperty("CoverPage", "false")));
        editor.putBoolean("TitlePageWrite", Boolean.parseBoolean(props.getProperty("TitlePageWrite", "false")));
        editor.putString("TitlePage", props.getProperty("TitlePage", ""));

        editor.putBoolean("TocPage", Boolean.parseBoolean(props.getProperty("TocPage", "false")));
        editor.putBoolean("TocVertical", Boolean.parseBoolean(props.getProperty("TocVertical", "false")));

        // 出力ファイル設定
        editor.putString("Ext", props.getProperty("Ext", ""));
        editor.putBoolean("AutoFileName", Boolean.parseBoolean(props.getProperty("AutoFileName", "false")));
        editor.putBoolean("OverWrite", Boolean.parseBoolean(props.getProperty("OverWrite", "false")));
        editor.putBoolean("MarkId", Boolean.parseBoolean(props.getProperty("MarkId", "false")));

        // 縦書き横書き
        editor.putBoolean("Vertical", Boolean.parseBoolean(props.getProperty("Vertical", "false")));

        // 文字コード
        if (props.getProperty("EncType") != null) {
            editor.putInt("EncType", Integer.parseInt(props.getProperty("EncType")));
        }

        // 言語設定
        editor.putString("LangType", props.getProperty("LangType", ""));

        // 画像設定
        editor.putBoolean("NoIllust", Boolean.parseBoolean(props.getProperty("NoIllust", "false")));
        editor.putInt("DispW", parseInt(props.getProperty("DispW")));
        editor.putInt("DispH", parseInt(props.getProperty("DispH")));

        // Jpeg圧縮率
        editor.putInt("JpegQuality", parseInt(props.getProperty("JpegQuality")));

        // 詳細設定
        editor.putBoolean("AutoYoko", Boolean.parseBoolean(props.getProperty("AutoYoko", "false")));
        editor.putBoolean("CommentPrint", Boolean.parseBoolean(props.getProperty("CommentPrint", "false")));

        // Web設定
        editor.putFloat("WebInterval", parseFloat(props.getProperty("WebInterval")));
        editor.putString("UserAgent", props.getProperty("UserAgent", ""));
        editor.putString("CachePath", props.getProperty("CachePath", ".cache"));
        editor.putBoolean("WebConvertUpdated", Boolean.parseBoolean(props.getProperty("WebConvertUpdated", "false")));

        // 変更を保存
        editor.apply();
    }

    private int parseInt(String value) {
        try {
            return value != null ? Integer.parseInt(value) : 0;
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    private float parseFloat(String value) {
        try {
            return value != null ? Float.parseFloat(value) : 0.0f;
        } catch (NumberFormatException e) {
            return 0.0f;
        }
    }
}

ポイント

  • SharedPreferencesを使い、アプリの設定を永続化。
  • parseIntとparseFloatで例外処理を行い、安全に変換。
  • apply()を使い非同期で保存(パフォーマンス向上)。

SharedPreferencesを使い、アプリの設定を永続化。

parseIntとparseFloatで例外処理を行い、安全に変換。

apply()を使い非同期で保存(パフォーマンス向上)。

このコードをアクティビティで使う場合は、以下のように呼び出せます:

PreferenceManager preferenceManager = new PreferenceManager(context);
preferenceManager.loadProperties(properties);

何かカスタマイズが必要なら教えてください!

あなた:

uiも書いて

ChatGPT:

AndroidでUIも含めてPreferenceManagerを利用できるように、設定画面(Preferences Screen)を作成しました。

構成:

  1. 設定のデータ管理 (PreferenceManager)
  2. 設定画面 (SettingsActivity & SettingsFragment)
  3. 設定画面のレイアウト (res/xml/preferences.xml)

設定のデータ管理 (PreferenceManager)

設定画面 (SettingsActivity & SettingsFragment)

設定画面のレイアウト (res/xml/preferences.xml)

SharedPreferencesを使って、プロパティを保存・読み込みします。

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import androidx.preference.PreferenceManager;
import java.util.Properties;

public class AppPreferenceManager {
    private SharedPreferences sharedPreferences;
    private SharedPreferences.Editor editor;

    public AppPreferenceManager(Context context) {
        this.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        this.editor = sharedPreferences.edit();
    }

    public void loadProperties(Properties props) {
        if (props == null) return;

        try {
            editor.putInt("TitleType", parseInt(props.getProperty("TitleType")));
            editor.putBoolean("PubFirst", Boolean.parseBoolean(props.getProperty("PubFirst", "false")));
            editor.putBoolean("UseFileName", Boolean.parseBoolean(props.getProperty("UseFileName", "false")));
            editor.putString("Cover", props.getProperty("Cover", ""));
            editor.putBoolean("CoverHistory", Boolean.parseBoolean(props.getProperty("CoverHistory", "false")));
            editor.putInt("MaxCoverLine", parseInt(props.getProperty("MaxCoverLine")));
            editor.putBoolean("CoverPage", Boolean.parseBoolean(props.getProperty("CoverPage", "false")));
            editor.putBoolean("TitlePageWrite", Boolean.parseBoolean(props.getProperty("TitlePageWrite", "false")));
            editor.putBoolean("TocPage", Boolean.parseBoolean(props.getProperty("TocPage", "false")));
            editor.putBoolean("TocVertical", Boolean.parseBoolean(props.getProperty("TocVertical", "false")));
            editor.putString("Ext", props.getProperty("Ext", ""));
            editor.putBoolean("AutoFileName", Boolean.parseBoolean(props.getProperty("AutoFileName", "false")));
            editor.putBoolean("OverWrite", Boolean.parseBoolean(props.getProperty("OverWrite", "false")));
            editor.putBoolean("MarkId", Boolean.parseBoolean(props.getProperty("MarkId", "false")));
            editor.putBoolean("Vertical", Boolean.parseBoolean(props.getProperty("Vertical", "false")));
            editor.putString("LangType", props.getProperty("LangType", ""));
            editor.putInt("JpegQuality", parseInt(props.getProperty("JpegQuality")));
            editor.putFloat("WebInterval", parseFloat(props.getProperty("WebInterval")));
            editor.putString("UserAgent", props.getProperty("UserAgent", ""));
            editor.putString("CachePath", props.getProperty("CachePath", ".cache"));

            editor.apply();
        } catch (Exception e) {
            Log.e("AppPreferenceManager", "Error saving preferences", e);
        }
    }

    private int parseInt(String value) {
        try {
            return value != null ? Integer.parseInt(value) : 0;
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    private float parseFloat(String value) {
        try {
            return value != null ? Float.parseFloat(value) : 0.0f;
        } catch (NumberFormatException e) {
            return 0.0f;
        }
    }
}

設定を表示・編集するための画面を作成します。

設定画面を開くアクティビティ。

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceFragmentCompat;

public class SettingsActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
        
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.settings_container, new SettingsFragment())
                .commit();
    }
}

設定の UI を管理する PreferenceFragmentCompat。

import android.os.Bundle;
import androidx.preference.PreferenceFragmentCompat;

public class SettingsFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.preferences, rootKey);
    }
}

ユーザーが変更できる設定の UI を作成。

res/xml/preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">

    <ListPreference
        app:key="TitleType"
        app:title="タイトルタイプ"
        app:dialogTitle="タイトルタイプを選択"
        app:entries="@array/title_types"
        app:entryValues="@array/title_type_values"
        app:defaultValue="0" />

    <SwitchPreferenceCompat
        app:key="PubFirst"
        app:title="PubFirst"
        app:defaultValue="false" />

    <SwitchPreferenceCompat
        app:key="UseFileName"
        app:title="ファイル名を使用"
        app:defaultValue="false" />

    <EditTextPreference
        app:key="Cover"
        app:title="表紙"
        app:dialogTitle="表紙のパスを入力"
        app:defaultValue="" />

    <SwitchPreferenceCompat
        app:key="CoverHistory"
        app:title="表紙履歴を有効化"
        app:defaultValue="false" />

    <SeekBarPreference
        app:key="JpegQuality"
        app:title="JPEG品質"
        app:min="0"
        app:max="100"
        app:defaultValue="75" />

    <EditTextPreference
        app:key="WebInterval"
        app:title="Web更新間隔(秒)"
        app:inputType="numberDecimal"
        app:defaultValue="60" />

    <EditTextPreference
        app:key="UserAgent"
        app:title="User-Agent"
        app:dialogTitle="User-Agent を入力"
        app:defaultValue="" />

    <SwitchPreferenceCompat
        app:key="WebConvertUpdated"
        app:title="Webの更新を変換"
        app:defaultValue="false" />

</PreferenceScreen>

res/values/arrays.xml に選択肢を定義。

<resources>
    <string-array name="title_types">
        <item>なし</item>
        <item>小</item>
        <item>中</item>
        <item>大</item>
    </string-array>

    <string-array name="title_type_values">
        <item>0</item>
        <item>1</item>
        <item>2</item>
        <item>3</item>
    </string-array>
</resources>

設定画面を開くために、MainActivity などから SettingsActivity を起動します。

Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);

✅ SharedPreferences を使用してプロパティを保存 ✅ SettingsActivity で設定画面を表示 ✅ PreferenceFragmentCompat を使用して UI を作成 ✅ スイッチ、リスト、テキスト入力、シークバーを活用

これで、アプリの設定を Android の SharedPreferences に保存し、UI から変更できるようになります。 追加機能やカスタマイズが必要なら教えてください! 🚀