2014年1月23日木曜日

[Glaeja] エクステンションのつくりかた

『Glaeja』ver.4.5.0から、「エクステンション」という外部アプリとの連携が可能になりました。

このエントリでは、エクステンションを自作するのに必要なライブラリの配布と、それを使ったサンプルコードの解説をおこないます。




ライブラリJar

『Glaeja』エクステンションを作成するためには、ライブラリJar“GlaejaExtension_v100.jar”を利用するのが便利です。Jarファイルは以下のリンクからダウンロードできます。



使い方


プロジェクトの「libs」フォルダにダウンロードしたJarファイルをコピーしてください。

エクステンションを作成するには、
  1. com.gmail.kanitawa.gex.GEXService”を継承したサービスを作成し、
  2. その中の“public String parseParam(String param)”メソッドをオーバーライドして、
  3. お好みの処理を実装してください。

エクステンションの初期化や破棄をおこなう場合には、適宜“onBind”や“onUnbind”をオーバーライドしてください。
ただし、“onUnbind”をオーバーライドする場合には、その返り値に注意してください(下記参照)。

エクステンションの仕組み


『Glaeja』エクステンションはサービスで構成されています。

『Glaeja』は、[データ管理]→[エクステンションの管理]→[新規登録]でエクステンションが登録されると、そのエクステンションを構成するサービス(com.gmail.kanitawa.gex.GEXService)に“bindService”でバインドし、そのコネクションを内部で保持します。

また同様に、[登録解除]でエクステンションの登録が解除されると、サービスを“unbindService”で開放します。
このとき、再バインド時に“onRebind”しないように“onUnbind”では「false」を返しています。

『Glaeja』は、ウィジェット描画の文字列解析時に「パラメータ文字列):(GEXコード)@.../.../\Z@」というエスケープキャラクタシーケンスが出現した場合、内部で保持しているエクステンション管理データベースから該当するGEXコードを持つエクステンションを探し、そのサービスの“parse(String)”メソッドを、パラメータ文字列を引数にして同期的に呼び出します。そして、“parse(String)”メソッドからの返り値である結果文字列で、「パラメータ文字列):(GEXコード)@.../.../\Z@」というエスケープキャラクタシーケンス全体を置換し、文字列解析を続行します。

なお、該当するGEXコードを持つエクステンションが見つからない場合には、 「パラメータ文字列):(GEXコード)@.../.../\Z@」というエスケープキャラクタシーケンスを全削除した後に文字列解析を続行します。


ライセンス


Copyright (c) 2014 kanitawa

ライブラリJar“GlaejaExtension_v100.jar”は、MITライセンスのもと公開されています。
http://opensource.org/licenses/mit-license.php


…著作権表記は「about」に表示したりするのが一般的ですが、個人的には「ストアの説明文」に表記しときゃイイんじゃないか、と考えています。



エクステンションのサンプルコード


『Glaeja』エクステンションの簡単なサンプルコードを用意しました。以下のリンクからダウンロードできます。

このサンプルコード「gex_sample」は、設定画面で選んだカッコ「( ... )、{ ... }、[ ... ]」でパラメータ文字列を囲む、という機能を実装したエクステンションになります。




使い方


ZIPアーカイブには
  • src/
  • res/
  • AndroidManifest.xml
  • LICENSE.txt
  • README.txt

しか入っていませんので、新規プロジェクトの適当なフォルダにコピーしてやってください。
また、上述したライブラリJar“GlaejaExtension_v100.jar”を「libs」フォルダにコピーしてください。


コードの解説


まず、“src/com.example.gex_sample/myGEXService”から。

package com.example.gex_sample;

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

import com.gmail.kanitawa.gex.GEXService;

public class myGEXService extends GEXService {

 @Override
 public String parseParam(String param) {
  // 共有プリファレンスから設定されているカッコの種類を取得
  final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
  int type = sp.getInt(SettingsActivity.TYPE_PAREN, SettingsActivity.PAREN_ROUND);

  // 渡された文字列を対応するカッコで囲んで返す
  switch (type) {
  case SettingsActivity.PAREN_ROUND: default:
   return "( "+param+" )";
  case SettingsActivity.PAREN_CURLY:
   return "{ "+param+" }";
  case SettingsActivity.PAREN_BOX:
   return "[ "+param+" ]";
  }
 }
}

これが、“com.gmail.kanitawa.gex.GEXService”を継承したエクステンション本体のサービスです。

オーバーライドした“public String parseParam(String param)”で、設定に従って選んだカッコで渡された文字列を囲んで、結果として返しています。

ここでは使っていませんが、エクステンション内部で初期化や破棄等が必要な場合には、“onBind”や“onUnbind”をオーバーライドすることもできます。


設定画面である“src/com.example.gex_sample/SettingsActivity”は省略します。


AndroidManifest.xml”ですが、サービスやアクティビティの登録以外に、『Glaeja』の[エクステンションの管理]で使う様々なパラメータの記述が必要です。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.gex_sample"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        <activity
            android:name="com.example.gex_sample.SettingsActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <service android:label="@string/app_name"
            android:name="myGEXService"
            android:icon="@drawable/ic_launcher"
            android:exported="true">
            <intent-filter>
                <action android:name="com.gmail.kanitawa.gex.IGEXService"/>
            </intent-filter>
            <meta-data android:name="description" android:value="説明文"/>
            <meta-data android:name="default_code" android:value="GEX_SAMPLE"/>
            <meta-data android:name="settings" android:value=".SettingsActivity"/>
        </service>
        
    </application>

</manifest>


サービスですが、インテントフィルターに
  • <action android:name="com.gmail.kanitawa.gex.IGEXService" />

を持つ必要があります。


また、属性として
  • android:label:エクステンションの管理画面における表示名。
  • android:icon:エクステンションの管理画面におけるアイコン。

を持たなければなりません。サンプルでは設定画面Activityと同じものを指定していますが、独自のものを割り当てても構いません。
このサービスはインテントフィルターを持つため、“android:exported”はなくてもデフォルトが「true」になります。


他にエクステンションの管理画面で必要となる情報として
  • <meta-data android:name="description" android:value="..." />
  • <meta-data android:name="default_code" android:value="..." />

の2つが必須となっています。

"description"は、管理画面の真ん中に表示されるもので、エクステンションの説明文です。
"default_code"は、説明文の下にある「GEXコード:」の初期文字列です。


オプショナルなデータとして、
  • <meta-data android:name="settings" android:value="..." />

を含んでいる場合、管理画面の右端に設定アイコンが表示され、クリックすることでエクステンションの設定アクティビティが起動します。


ライセンス


Copyright (c) 2014 kanitawa

このサンプルコードは、MITライセンスのもと公開されています。
http://opensource.org/licenses/mit-license.php

0 件のコメント:

コメントを投稿