Androidで使える背景画像を作ってみた

久しぶりのブログ更新です。
最近はブログのネタ切れで困っていたんですが、これからはAndroidで使えるアイコンや画像を中心に
ブログを更新して行こうと思います。


今回はTextViewなどで使える背景画像を作ってみました。



9ピッチ形式ですので、画像が拡大されてブレると言う事もありません。



こんな感じで使えます。

<TextView 
    android:background="@drawable/balloon_bak"
    android:textColor="@color/olivedrab"
    android:gravity="center"
    android:textSize="18sp"
    android:text="@string/schedule_memo"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>



ライセンスはフリーですので、ご自由にお使い下さい。
※ブログ等で再配布はおやめ下さい。


ダウンロードはこちらから↓
https://sites.google.com/site/devkorsakov/files/balloon_bak.9.png?attredirects=0&d=1

RatingBarの画像を変更してみる



今回はRatingbarの画像を変更してみます。



今作ってるアプリでRatingbarを使ってみようと思ったんですが、
表示される画像が機種によってまちまちなので、
自分で作った☆の画像を設定してみようと思います。

画像を作成

InkscapeとかGimpで適当に☆を作ります。
3パターン必要です。


  • ☆の設定されていない状態
  • ☆が半分設定された状態
  • ☆が完全に設定された状態



名前は適当にbtn01,btn02,btn03としておきます。


次にstyle.xmlとrating.xmlを作成します。

style.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MyRating" parent="@android:style/Widget.RatingBar">
        <item name="android:progressDrawable">@drawable/rating</item>
        <item name="android:minHeight">38dip</item>
        <item name="android:maxHeight">38dip</item>
        <item name="android:thumb">@null</item>
        <item name="android:isIndicator">true</item>
    </style>
</resources>


rating.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+android:id/background" 
        android:drawable="@drawable/btn01" />
    <item android:id="@+android:id/secondaryProgress" 
        android:drawable="@drawable/btn02" />
    <item android:id="@+android:id/progress" 
        android:drawable="@drawable/btn03" />
</layer-list>



これらの画像とXMLをdrawableフォルダに入れておきます。
※drawableの全てのフォルダに入れるか、no-dpiに入れるかしないとエラーになるので注意が必要です。


実際に使ってみる
<RatingBar 
    android:numStars="5"
    android:stepSize="0.5"
    android:rating="1"
    android:layout_gravity="center_horizontal"
    style="@style/MyRating"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

style="@style/MyRating"とすることで、
オリジナルのスタイルを適用できます。



今回はこちらのサイトを参考にしました。
http://kozyr.zydako.net/2010/05/23/pretty-ratingbar/

インストールされてる端末の型番について調べてみた



久しぶりにブログの更新です。
今回はAndroid端末の型番を少しだけまとめたので、記事にしてみました。
型番とはSC-02BやSO-02Cなどの事。SC-02BはGalaxy S。SO-02CはXperia Acroです。
つい最近になって、デベロッパーコンソール(デベコン)でも型番の横に名称が表示されるようになりましたが、
Otherとなってる端末は詳細は不明です。
無料アプリの場合はこれ以上知る術はないのですが、有料アプリだと売上情報を詳細に記載したPayoutReportがダウンロード出来ます。


このレポートを見れば、より詳細なインストール端末を見ることができますが、端末名は型番しか書かれていません。(不親切ですよね)
そこで、かんたん家計簿Proにインストールされた型番を調べて一覧にしました。ついでに、かんたん家計簿Proのインストール状況も公開してみます。

型番と端末名称

型番:端末名称
aceGalaxy Ace
blazeAlcatel onetouch Blaze Duo
bravoMotorola Bravo
DM009SHDM009SH
DM010SHDM010SH
eliniOptimus chat L-04C ?
es209raROM
f11eifF-12C
f11skyF-03D
GalapagosGalapagos
GT-I9000Galaxy S (海外製?)
hwu8510Huawei U8510
IS11CAG'zOne IS11CA
IS11SXperia Acro (au)
jmasaiIS06
KYI11DIGNO ISW11K
L-07COptimus bright L-07C
libertyHTC Aria
LTNA7NEC LT-NA7
LTNA7FNEC LT-NA7F
mirachj MIRACH IS11PT
N-04CMedias N-04C
N-06CMEDIAS WP N-06C
pana1SV-MV100…?
SBM003SHGALAPAGOS
SBM005SHGALAPAGOS 005SH
SBM006SHSBM006SH
SBM007SHSBM007SH
SBM007SHJSBM007SHJ
SBM009SH009SH
SC-01CGalaxy Tab
SC-02BGalaxy S
SC-02CGalaxy S 2
SC-03DGALAXY S II LTE
SH01DAQUOS PHONE SH-01D
SH02DAQUOS PHONE slider SH-02D
SH03CLynx3DSH-03C
SH10BLYNX SH-10B
SH12CAQUOS PHONE SH-12C
SH13CAQUOS PHONE f SH-13C
SHI01IS01
SHI03IS03
SHI05IS05
SHI11IS11SH
SHI12IS12SH
SHI13AQUOS PHONE IS13SH
shooterk?
SHX11INFOBAR A01
SMT-i9100SMT-i9100
SO-01BXperia X10
SO-01CXperia Arc
SO-02CXperia Acro
SO-03CXperiaRay
SonyEricssonSO-01BXperiaX10 (1.6?)
streakDell Streak
sunfireMotorola Sunfire
supersonicHTC EVO 4G
tg03RegzaT01C
TSI11TOSHIBA IS11T
umts_spyderROM?
YP-GB70Galaxy Player


意外にも、海外製の端末を使ってる人は結構いるんですね。かんたん家計簿は日本でしか公開していないから、
外国人は使っていないはずです。
shooterkって結構調べたけど全然分からなかったです。誰か知ってる人いたら教えてください。


次はかんたん家計簿Proのインストール状況です。
半年も経つのに、あまり売れてません(涙

アプリのインストール台数



キャリア別




やはりよく売れているGalaxyS、S2の利用者が多いですね。
RegzaPhoneT-01Cも多いですけど、そのうちGalaxyシリーズが抜くような気がします。
僕のアプリはGalaxyシリーズと相性が良いのでしょうか。特に不具合も報告ありません。
逆にSharpシリーズは何かと不具合の報告が多いです。僕のアプリが悪いのかな?それとも端末が…


キャリア別で見るとDOCOMOAUソフバンの順です。中にはカスタムROMを使ってるユーザーも居るんですね。
Otherは海外の端末です。多分b-mobileで運用してるんだと思います。

オススメアプリ その1

久しぶりにブログの更新です。
最近はブログを書くネタがなくて非常に困ってますが、
これから暇を見つけては、僕のオススメアプリを紹介していきます。

Battery Widget

とてもシンプルで見やすいバッテリー管理ウィジェットです。
タスクバーに格納するタイプはコンパクトで良いんですが、
残量が確認しづらいのがネックですね。


その点、このBattery Widgetはアプリ一個分のスペースで、
ウィジェットが置けて便利ですね。



Battery Widget





AutoRotate Switch

Androidアプリの開発をしていると、どうしても横画面でのテストが必要ですよね。
そんな時一々設定画面から縦横固定を切り替えるのは、正直面倒くさい。
そんな時に便利なのが、このAutoRotate Switchです。
ウィジェットなので切り替えが早く、とても良いです。



AutoRotate Switch





Watchdog Task Manager Lite

常駐アプリのメモリ使用量やCPU使用率を表示してくれる、大変便利なアプリケーションです。
端末に負荷のかかる動作をしているアプリを、自動で知らせてくれたりもします。
バックグラウンドでどんなアプリが走ってるのか気になる人や、アプリの動作が重いなと感じたら、
とりあえずインストールして見ることをお勧めします。



Watchdog Task Manager Lite





RockPlayer Lite

様々な拡張子に対応した動画再生プレーヤーです。FLVとかも再生できます。
入れておいて損はないアプリの一つですね。



RockPlayer Lite





Perfect Viewer

非常に使いやすく、動作の軽い画像ビューワーです。
UIがなかなか洗練されていて、素早く的確な操作ができるのも素晴らしいです。
使い慣れると他のビューワーには戻れませんね。



Perfect Viewer





AndroidでPDFを作成してみる



こんにちは。久しぶりのブログ更新です。


今回はAndroidアプリから、PDFファイルを作成する方法を紹介したいと思います。



実現方法としては・・・

  1. 既存ライブラリを活用する
  2. 自前でスクリプトを書く
  3. PDFを生成してくれるWebサービスを利用する
  4. 他アプリからインテントを使い生成する
僕自身、全て試したわけではありませんが、手っ取り早いのは(1)既存のライブラリを活用する事だと思います。実装が一筋縄ではありませんが・・・


(2)に関しては、PDFの仕様を理解していないとイバラの道になると思います。
でも仕様を理解することは勉強にもなるし、時間に余裕のある人はこちらをオススメします。(日本語訳の公式リファレンスが5、6千円で売ってます。英語のリファレンスはWebで無料でダウンロードできます)
(3)に関しては2ch仕入れた情報ですが、面倒臭そうなので調べていません…
(4)調べたんですが、今のところ無さそうです。。。(もしあれば教えてください)

既存のライブラリを利用してみる

これより先はライブラリの利用方法について説明しますが、フリーのライブラリを利用する際、
いくつか注意する事があります。

  1. ライブラリが利用しているjavaパッケージ
  2. ライブラリが利用しているJDKのバージョン(JDK6を使ってたらアウト)
  3. 日本語等の出力
  4. ライセンス
これらすべての条件を満たすライブラリとなると、かなり数が限られてきそうです。
特にライセンスは重要です。調べれば分かることですが、GPL関連のライセンスだと利用するのが難しいでしょう。
うろ覚えですが、「GPLライセンスのライブラリを利用する際の条約の一つとして、アプリに組み込まれたライブラリが改変された場合はソースコードを開示しなければいけない。Androidではこの条約を満たすことが出来ないから、結局ソースコードを開示する必要がある」どこかのブログに書いてあった気がします。。。回避策としては、PDFに関連する処理だけを抜き出し、別アプリで公開後、インテント経由で利用するということが考えられます。でもユーザーにアプリのインストール促す必要もあり、いろいろ面倒ですね。。。

なんとなく使えそうなライブラリ

java PDF ライブラリ」でググルと結構ヒットしますが、どれもコレも一筋縄ではいきません。

java用のPDFライブラリ
ライブラリ名 packageのサポート JDKバージョン 日本語出力 ライセンス
iText × ×
iText for Android ×
PDF Box ×
Android PDF Write ×


iText
iTextはドキュメントも豊富で、ブログ等で使い方も紹介されているぐらいメジャー?なライブラリのようですが、
awt等のAndroidではサポートされないパッケージを使ってます。
実際にiTextを実装する際、この事に気づくまで1週間ぐらいハマってしまいました。
しかもGPLの派生ライセンスを採用しています。


iText for Android
iTextAndroidで使えるようにしてるらしいですが、どうやらまだ未完成のようです。
実際試しましたが、結局ビルドが通りませんでした。


PDF Box
こちらは試してませんが、やっぱりパッケージ関連の問題で無理なようです。
http://www.kaede-software.com/2011/04/pdfbox.html


Android PDF Write
恐らくつい最近に公開されたAndroid用のライブラリですが、外国の方が作られたライブラリなので日本語等の出力が無理なようです。英語のドキュメントのみ生成するのであれば、十分利用出来ます。


色々なライブラリを調べた結果、「androidで利用出来るjavaのPDFライブラリ」は今のところ無さそうです・・・

NDKを利用する

それからかなり悩んだのですが、javaが無理ならCのライブラリはどうだ?と色々探してみたところ、
libHaru free PDF library」を見つけました。
ドキュメント等は全て英語のなのですが、製作者は日本の方なので、日本語の出力も可能です。
ライセンスは zlib/libpngライセンスなので、商用・非商用を問わずアプリに組み込めそうです。
ダウンロード・ドキュメントはこちら
http://libharu.org/wiki/Main_Page


これよりNDKの環境構築とビルドに関して説明していきます。環境を整えるのが結構面倒ですが、それに見合った価値はあると思います。
(とりあえず動きを確認したい場合は、ページ最下部にプロジェクトをダウンロードできるURLを貼りつけています)

NDKの開発環境を整える

環境構築に関しては、分かりやすく解説されているサイトが多数存在しますので、頑張って調べてください。
僕はこちらのサイトを参考にさせていただきました。
http://www.usefullcode.net/2010/12/android_sdk_inst05.html
http://d.hatena.ne.jp/bs-android/20090324/1237864333

ネィティブモジュールを呼び出す準備

クラスファイルにネィティブを使うことを宣言します。

static {
    System.loadLibrary("CreatePDF");
}
private native int createPDF(String fpath);



exportボタンを押すと、SyncTaskが起動してPDFを作成するようにします。

@Override
public void onCreate(Bundle savedInstanceState) {
    
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    Button b = (Button)this.findViewById(R.id.Button01);
    b.setOnClickListener(new OnClickListener() {
        
        @Override
        public void onClick(View v) {
            
            switch (v.getId()) {
            case R.id.Button01:
                
                export();
                break;
            default:
                break;
            }
        }
    });
}

プログレスダイアログを表示して、ネイティブに処理を任せる。

private void export() {
    
    final ProgressDialog mProgress =
        new ProgressDialog(this);
    mProgress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    mProgress.setMessage(getResources().getString(R.string.wait));
    mProgress.setCancelable(false);
    
    Runnable successRun = new Runnable() {
        public void run() {
            
            Toast.makeText(getApplicationContext(),
                    getResources().getString(R.string.success),
                    Toast.LENGTH_SHORT).show();
            mProgress.dismiss();
            setResult(RESULT_OK);
        };
    };
    Runnable errorRun = new Runnable() {
        public void run() {
            
            Toast.makeText(getApplicationContext(),
                    getResources().getString(R.string.error),
                    Toast.LENGTH_SHORT).show();
            mProgress.dismiss();
        };
    };
    
    
    mProgress.show();
    ExportSyncTask task = new ExportSyncTask(
            this.getApplicationContext(),
            successRun, errorRun);
    task.execute();
}

private String getSavePath(String catStr) throws IOException {
    
    String pathSd = new StringBuilder()
        .append(Environment.getExternalStorageDirectory().getPath())
        .append("/")
        .append(this.getPackageName())
        .toString();
    File filePathToSaved = new File(pathSd);
    
    if (!filePathToSaved.exists() && !filePathToSaved.mkdirs()) {
        throw new IOException("FAILED_TO_CREATE_PATH_ON_SD");
    }
    
    return pathSd + "/" + catStr;
}

public int exportPDF () throws FileNotFoundException, IOException {
    
    String savePath;
    savePath = getSavePath("helloPDF.pdf");
    createPDF(savePath);

    return 0;
}

private class ExportSyncTask extends AsyncTask<Void, Void, Integer> {

    private Handler mHandler;
    private Handler mHandler2;
    private Thread mSuccessT;
    private Thread mErrorT;
    
    public ExportSyncTask(Context context, final Runnable r1, final Runnable r2) {
        
        mHandler = new Handler();
        mHandler2 = new Handler();
        
        mSuccessT = new Thread(new Runnable() {
            public void run() {
                mHandler.post(r1);
            }
        });
        
        mErrorT = new Thread(new Runnable() {
            public void run() {
                mHandler2.post(r2);
            }
        });
    }
    
    @Override
    protected Integer doInBackground(Void... arg0) {
        
        try {
            exportPDF();
        } catch (FileNotFoundException e) {
            Log.e("PDF_sampleActivity", e.toString());
            return -1;
        } catch (IOException e) {
            Log.e("PDF_sampleActivity", e.toString());
            return -1;
        }
        
        return 0;
    }
    
    @Override
    protected void onPostExecute(Integer result) {
        
        if (result == null || result < 0) {
            
            mErrorT.start();
        } else {
            
            mSuccessT.start();
        }
    }
}



マニフェストパーミッションを追加しておきます。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>



「CreatePDF」はこれから作成するライブラリの名前になります。
javad側の処理はこれで完了です。
ここで一旦ビルドしてください。

ソースコードをダウンロードする

AndroidでlibHaruPDFを使うには、ソースコードコンパイルしてAndroid用の共有ライブラリを作成する必要があります。
libHaruPDFはlibpngライブラリーを使用しておりますので、libHaruPDFとlibpngのソースコードをダウンロードしましょう。
libHaruPDF
http://libharu.org/wiki/Downloads
(Latest Versionをダウンロードして下さい)


libpng
http://www.libpng.org/pub/png/libpng.html
(バージョン1.2.46のsource codeよりダウンロードして下さい)


ではeclipseにフォルダを作って、ファイルを移動しましょう。
jniフォルダを作り、その中にlibharu,libpng,pdftestの3フォルダを作ります。
フォルダ構成は次のようになってると思います。(*.c,*.hのみ移動させます。その他のmakeとか必要ないです)

top
  src
  gen
  assets
  libs
  res
  jni
  --libharu
    --include
      --hpdf_annotation.h
      --hpdf_catalog.h
      --hpdf_conf.h
      --...
    --hpdf_annotation.c
    --hpdf_array.c
    --hpdf_binary.c
    --...
  --libpng
    --<*.hと*.cを全て>
  --pdftest

pdftestフォルダにCreatePDFとヘッダファイルを配置します。
こちらのブログを参考にヘッダファイルを作成します。(「JNIヘッダファイルの生成」の項を参照)
http://d.hatena.ne.jp/bs-android/20090324/1237864333
次にCreatePDF.cを作成してください。
下記URLのサンプルコードを試してみます。(コピペでは動きません)
http://libharu.org/wiki/Documentation/Examples

/*
 * << Haru Free PDF Library 2.0.0 >> -- font_demo.c
 *
 * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.
 * It is provided "as is" without express or implied warranty.
 *
 */

#include <sample_pdf_PDFsampleActivity.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include "hpdf.h"
#include <android/log.h>

jmp_buf env;

static char* jstr2cp(JNIEnv *e, jstring str);
static void jstrfree(JNIEnv *e, jstring str, char *cp);
static void log_print(char *str);

#ifdef HPDF_DLL
void  __stdcall
#else
void
#endif
error_handler (HPDF_STATUS   error_no,
               HPDF_STATUS   detail_no,
               void         *user_data)
{
    __android_log_print(ANDROID_LOG_DEBUG, "CreatePDF",
    			"ERROR: error_no=%04X, detail_no=%u\n", (HPDF_UINT)error_no,
                (HPDF_UINT)detail_no);
    longjmp(env, 1);
}

void
draw_line  (HPDF_Page    page,
            float        x,
            float        y,
            const char  *label)
{
    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, x, y - 10);
    HPDF_Page_ShowText (page, label);
    HPDF_Page_EndText (page);

    HPDF_Page_MoveTo (page, x, y - 15);
    HPDF_Page_LineTo (page, x + 220, y - 15);
    HPDF_Page_Stroke (page);
}

void
draw_line2  (HPDF_Page    page,
             float       x,
             float       y,
             const char  *label)
{
    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, x, y);
    HPDF_Page_ShowText (page, label);
    HPDF_Page_EndText (page);

    HPDF_Page_MoveTo (page, x + 30, y - 25);
    HPDF_Page_LineTo (page, x + 160, y - 25);
    HPDF_Page_Stroke (page);
}

void
draw_rect (HPDF_Page     page,
           double        x,
           double        y,
           const char   *label)
{
    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, x, y - 10);
    HPDF_Page_ShowText (page, label);
    HPDF_Page_EndText (page);

    HPDF_Page_Rectangle(page, x, y - 40, 220, 25);
}

JNIEXPORT jint JNICALL Java_sample_pdf_PDFsampleActivity_createPDF
  (JNIEnv *jenv, jobject jobj, jstring file_name)
{
    const char* page_title = "Line Example";

    HPDF_Doc  pdf;
    HPDF_Font font;
    HPDF_Page page;
    char fname[256];
    char *path_str;

    const HPDF_UINT16 DASH_MODE1[] = {3};
    const HPDF_UINT16 DASH_MODE2[] = {3, 7};
    const HPDF_UINT16 DASH_MODE3[] = {8, 7, 2, 7};

    double x;
    double y;
    double x1;
    double y1;
    double x2;
    double y2;
    double x3;
    double y3;

    float tw;

    path_str = jstr2cp(jenv, file_name);
	strcpy (fname, path_str);

    pdf = HPDF_New (error_handler, NULL);
    if (!pdf) {
        log_print ("error: cannot create PdfDoc object\n");
        return 1;
    }

    if (setjmp(env)) {
        HPDF_Free (pdf);
        return 1;
    }

    /* create default-font */
    font = HPDF_GetFont (pdf, "Times-Roman", NULL);

    /* add a new page object. */
    page = HPDF_AddPage (pdf);
    
    log_print("new page");

    /* print the lines of the page. */
    HPDF_Page_SetLineWidth (page, 1);
    HPDF_Page_Rectangle (page, 50, 50, HPDF_Page_GetWidth(page) - 100,
                HPDF_Page_GetHeight (page) - 110);
    HPDF_Page_Stroke (page);

    /* print the title of the page (with positioning center). */
    HPDF_Page_SetFontAndSize (page, font, 24);
    tw = HPDF_Page_TextWidth (page, page_title);
    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, (HPDF_Page_GetWidth(page) - tw) / 2,
                HPDF_Page_GetHeight (page) - 50);
    HPDF_Page_ShowText (page, page_title);
    HPDF_Page_EndText (page);

    HPDF_Page_SetFontAndSize (page, font, 10);

    /* Draw verious widths of lines. */
    HPDF_Page_SetLineWidth (page, 0);
    draw_line (page, 60, 770, "line width = 0");

    HPDF_Page_SetLineWidth (page, 1.0);
    draw_line (page, 60, 740, "line width = 1.0");

    HPDF_Page_SetLineWidth (page, 2.0);
    draw_line (page, 60, 710, "line width = 2.0");

    /* Line dash pattern */
    HPDF_Page_SetLineWidth (page, 1.0);

    HPDF_Page_SetDash (page, DASH_MODE1, 1, 1);
    draw_line (page, 60, 680, "dash_ptn=[3], phase=1 -- "
                "2 on, 3 off, 3 on...");

    HPDF_Page_SetDash (page, DASH_MODE2, 2, 2);
    draw_line (page, 60, 650, "dash_ptn=[7, 3], phase=2 -- "
                "5 on 3 off, 7 on,...");

    HPDF_Page_SetDash (page, DASH_MODE3, 4, 0);
    draw_line (page, 60, 620, "dash_ptn=[8, 7, 2, 7], phase=0");

    HPDF_Page_SetDash (page, NULL, 0, 0);

    HPDF_Page_SetLineWidth (page, 30);
    HPDF_Page_SetRGBStroke (page, 0.0, 0.5, 0.0);

    /* Line Cap Style */
    HPDF_Page_SetLineCap (page, HPDF_BUTT_END);
    draw_line2 (page, 60, 570, "PDF_BUTT_END");

    HPDF_Page_SetLineCap (page, HPDF_ROUND_END);
    draw_line2 (page, 60, 505, "PDF_ROUND_END");

    HPDF_Page_SetLineCap (page, HPDF_PROJECTING_SCUARE_END);
    draw_line2 (page, 60, 440, "PDF_PROJECTING_SCUARE_END");

    /* Line Join Style */
    HPDF_Page_SetLineWidth (page, 30);
    HPDF_Page_SetRGBStroke (page, 0.0, 0.0, 0.5);

    HPDF_Page_SetLineJoin (page, HPDF_MITER_JOIN);
    HPDF_Page_MoveTo (page, 120, 300);
    HPDF_Page_LineTo (page, 160, 340);
    HPDF_Page_LineTo (page, 200, 300);
    HPDF_Page_Stroke (page);

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, 60, 360);
    HPDF_Page_ShowText (page, "PDF_MITER_JOIN");
    HPDF_Page_EndText (page);

    HPDF_Page_SetLineJoin (page, HPDF_ROUND_JOIN);
    HPDF_Page_MoveTo (page, 120, 195);
    HPDF_Page_LineTo (page, 160, 235);
    HPDF_Page_LineTo (page, 200, 195);
    HPDF_Page_Stroke (page);

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, 60, 255);
    HPDF_Page_ShowText (page, "PDF_ROUND_JOIN");
    HPDF_Page_EndText (page);

    HPDF_Page_SetLineJoin (page, HPDF_BEVEL_JOIN);
    HPDF_Page_MoveTo (page, 120, 90);
    HPDF_Page_LineTo (page, 160, 130);
    HPDF_Page_LineTo (page, 200, 90);
    HPDF_Page_Stroke (page);

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, 60, 150);
    HPDF_Page_ShowText (page, "PDF_BEVEL_JOIN");
    HPDF_Page_EndText (page);

    /* Draw Rectangle */
    HPDF_Page_SetLineWidth (page, 2);
    HPDF_Page_SetRGBStroke (page, 0, 0, 0);
    HPDF_Page_SetRGBFill (page, 0.75, 0.0, 0.0);

    draw_rect (page, 300, 770, "Stroke");
    HPDF_Page_Stroke (page);

    draw_rect (page, 300, 720, "Fill");
    HPDF_Page_Fill (page);

    draw_rect (page, 300, 670, "Fill then Stroke");
    HPDF_Page_FillStroke (page);

    /* Clip Rect */
    HPDF_Page_GSave (page);  /* Save the current graphic state */
    draw_rect (page, 300, 620, "Clip Rectangle");
    HPDF_Page_Clip (page);
    HPDF_Page_Stroke (page);
    HPDF_Page_SetFontAndSize (page, font, 13);

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, 290, 600);
    HPDF_Page_SetTextLeading (page, 12);
    HPDF_Page_ShowText (page,
                "Clip Clip Clip Clip Clip Clipi Clip Clip Clip");
    HPDF_Page_ShowTextNextLine (page,
                "Clip Clip Clip Clip Clip Clip Clip Clip Clip");
    HPDF_Page_ShowTextNextLine (page,
                "Clip Clip Clip Clip Clip Clip Clip Clip Clip");
    HPDF_Page_EndText (page);
    HPDF_Page_GRestore (page);

    /* Curve Example(CurveTo2) */
    x = 330;
    y = 440;
    x1 = 430;
    y1 = 530;
    x2 = 480;
    y2 = 470;
    x3 = 480;
    y3 = 90;

    HPDF_Page_SetRGBFill (page, 0, 0, 0);

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, 300, 540);
    HPDF_Page_ShowText (page, "CurveTo2(x1, y1, x2. y2)");
    HPDF_Page_EndText (page);

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, x + 5, y - 5);
    HPDF_Page_ShowText (page, "Current point");
    HPDF_Page_MoveTextPos (page, x1 - x, y1 - y);
    HPDF_Page_ShowText (page, "(x1, y1)");
    HPDF_Page_MoveTextPos (page, x2 - x1, y2 - y1);
    HPDF_Page_ShowText (page, "(x2, y2)");
    HPDF_Page_EndText (page);

    HPDF_Page_SetDash (page, DASH_MODE1, 1, 0);

    HPDF_Page_SetLineWidth (page, 0.5);
    HPDF_Page_MoveTo (page, x1, y1);
    HPDF_Page_LineTo (page, x2, y2);
    HPDF_Page_Stroke (page);

    HPDF_Page_SetDash (page, NULL, 0, 0);

    HPDF_Page_SetLineWidth (page, 1.5);

    HPDF_Page_MoveTo (page, x, y);
    HPDF_Page_CurveTo2 (page, x1, y1, x2, y2);
    HPDF_Page_Stroke (page);

    /* Curve Example(CurveTo3) */
    y -= 150;
    y1 -= 150;
    y2 -= 150;

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, 300, 390);
    HPDF_Page_ShowText (page, "CurveTo3(x1, y1, x2. y2)");
    HPDF_Page_EndText (page);

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, x + 5, y - 5);
    HPDF_Page_ShowText (page, "Current point");
    HPDF_Page_MoveTextPos (page, x1 - x, y1 - y);
    HPDF_Page_ShowText (page, "(x1, y1)");
    HPDF_Page_MoveTextPos (page, x2 - x1, y2 - y1);
    HPDF_Page_ShowText (page, "(x2, y2)");
    HPDF_Page_EndText (page);

    HPDF_Page_SetDash (page, DASH_MODE1, 1, 0);

    HPDF_Page_SetLineWidth (page, 0.5);
    HPDF_Page_MoveTo (page, x, y);
    HPDF_Page_LineTo (page, x1, y1);
    HPDF_Page_Stroke (page);

    HPDF_Page_SetDash (page, NULL, 0, 0);

    HPDF_Page_SetLineWidth (page, 1.5);
    HPDF_Page_MoveTo (page, x, y);
    HPDF_Page_CurveTo3 (page, x1, y1, x2, y2);
    HPDF_Page_Stroke (page);

    /* Curve Example(CurveTo) */
    y -= 150;
    y1 -= 160;
    y2 -= 130;
    x2 += 10;

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, 300, 240);
    HPDF_Page_ShowText (page, "CurveTo(x1, y1, x2. y2, x3, y3)");
    HPDF_Page_EndText (page);

    HPDF_Page_BeginText (page);
    HPDF_Page_MoveTextPos (page, x + 5, y - 5);
    HPDF_Page_ShowText (page, "Current point");
    HPDF_Page_MoveTextPos (page, x1 - x, y1 - y);
    HPDF_Page_ShowText (page, "(x1, y1)");
    HPDF_Page_MoveTextPos (page, x2 - x1, y2 - y1);
    HPDF_Page_ShowText (page, "(x2, y2)");
    HPDF_Page_MoveTextPos (page, x3 - x2, y3 - y2);
    HPDF_Page_ShowText (page, "(x3, y3)");
    HPDF_Page_EndText (page);

    HPDF_Page_SetDash (page, DASH_MODE1, 1, 0);

    HPDF_Page_SetLineWidth (page, 0.5);
    HPDF_Page_MoveTo (page, x, y);
    HPDF_Page_LineTo (page, x1, y1);
    HPDF_Page_Stroke (page);
    HPDF_Page_MoveTo (page, x2, y2);
    HPDF_Page_LineTo (page, x3, y3);
    HPDF_Page_Stroke (page);

    HPDF_Page_SetDash (page, NULL, 0, 0);

    HPDF_Page_SetLineWidth (page, 1.5);
    HPDF_Page_MoveTo (page, x, y);
    HPDF_Page_CurveTo (page, x1, y1, x2, y2, x3, y3);
    HPDF_Page_Stroke (page);
    
    log_print("end Stroke");

    /* save the document to a file */
    log_print (fname);
    HPDF_SaveToFile (pdf, fname);
    log_print ("save success");

    /* clean up */
    HPDF_Free (pdf);
    jstrfree(jenv, file_name, path_str);

    return 0;
}


static void jstrfree(JNIEnv *e, jstring str, char *cp)
{
	(*e)->ReleaseStringUTFChars(e, str, cp);
}

static char* jstr2cp(JNIEnv *e, jstring str)
{
	return (*e)->GetStringUTFChars(e, str, NULL);
}

static void log_print(char *str)
{
	__android_log_print(ANDROID_LOG_DEBUG, "CreatePDF", "%s", str);
}

Android.mkの書き方
モジュールをビルドするためのmakeファイルも書きますが、今回は自分の書いたmakeファイルを載せておきますので活用してください。
makeファイルの書き方は、こちらを参考にさせていただきました。
http://android.g.hatena.ne.jp/n4_t/20090703/1246674762
http://playwithopencv.blogspot.com/2011/06/androidopencv23.html

############### libpng ###############
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := png
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lz -ldl -llog

LOCAL_CFLAGS := -I$(LOCAL_PATH)/libpng
LOCAL_SRC_FILES := \
libpng/pngwrite.c \
libpng/pngrutil.c \
libpng/pngrtran.c \
libpng/pngread.c \
libpng/pngmem.c \
libpng/pngrio.c \
libpng/pngpread.c \
libpng/pngvcrd.c \
libpng/pngtrans.c \
libpng/pnggccrd.c \
libpng/pngwutil.c \
libpng/pngwio.c \
libpng/png.c \
libpng/pngwtran.c \
libpng/pngget.c \
libpng/pngset.c \
libpng/pngerror.c \

include $(BUILD_STATIC_LIBRARY)


############### libharu PDF Library ###############
include $(CLEAR_VARS)

LOCAL_MODULE := haru
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lz -ldl -llog \
-L$(TARGET_OUT) -lpng

LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/libpng \
$(LOCAL_PATH)/libharu/include

LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%)

LOCAL_SRC_FILES := \
libharu/hpdf_xref.c \
libharu/hpdf_annotation.c \
libharu/hpdf_array.c \
libharu/hpdf_binary.c \
libharu/hpdf_boolean.c \
libharu/hpdf_catalog.c \
libharu/hpdf_destination.c \
libharu/hpdf_dict.c \
libharu/hpdf_doc.c \
libharu/hpdf_doc_png.c \
libharu/hpdf_encoder.c \
libharu/hpdf_encoder_cns.c \
libharu/hpdf_encoder_cnt.c \
libharu/hpdf_encoder_jp.c \
libharu/hpdf_encoder_kr.c \
libharu/hpdf_encrypt.c \
libharu/hpdf_encryptdict.c \
libharu/hpdf_error.c \
libharu/hpdf_ext_gstate.c \
libharu/hpdf_font.c \
libharu/hpdf_font_cid.c \
libharu/hpdf_font_tt.c \
libharu/hpdf_font_type1.c \
libharu/hpdf_fontdef.c \
libharu/hpdf_fontdef_base14.c \
libharu/hpdf_fontdef_cid.c \
libharu/hpdf_fontdef_cns.c \
libharu/hpdf_fontdef_cnt.c \
libharu/hpdf_fontdef_jp.c \
libharu/hpdf_fontdef_kr.c \
libharu/hpdf_fontdef_tt.c \
libharu/hpdf_fontdef_type1.c \
libharu/hpdf_gstate.c \
libharu/hpdf_image.c \
libharu/hpdf_image_png.c \
libharu/hpdf_info.c \
libharu/hpdf_list.c \
libharu/hpdf_mmgr.c \
libharu/hpdf_name.c \
libharu/hpdf_namedict.c \
libharu/hpdf_null.c \
libharu/hpdf_number.c \
libharu/hpdf_objects.c \
libharu/hpdf_outline.c \
libharu/hpdf_page_label.c \
libharu/hpdf_page_operator.c \
libharu/hpdf_pages.c \
libharu/hpdf_pdfa.c \
libharu/hpdf_real.c \
libharu/hpdf_streams.c \
libharu/hpdf_string.c \
libharu/hpdf_u3d.c \
libharu/hpdf_utils.c \


LOCAL_STATIC_LIBRARIES := png
include $(BUILD_STATIC_LIBRARY)


############### pdf export ###############
include $(CLEAR_VARS)

LOCAL_MODULE := CreatePDF
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -lz -ldl -llog
# -L$(TARGET_OUT) -lharu

LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/pdf_export \
$(LOCAL_PATH)/libharu/include

LOCAL_CFLAGS := $(LOCAL_C_INCLUDES:%=-I%)

LOCAL_SRC_FILES := pdf_export/CreatePDF.c

LOCAL_STATIC_LIBRARIES := haru

include $(BUILD_SHARED_LIBRARY)



Cygwinを起動して、Android.mkがあるフォルダにて「ndk-build」を実行すれば、ソースがコンパイルされます。


コンパイルが完了するとlibsに共有ライブラリが作成されているはずです。
うまく行ったことが確認できたら、ビルドを実行して実機にインストールしてください。


作成されたPDFは、AdobeReaderにて確認してみてください。


プロジェクトはダウンロードする場合はこちら

https://sites.google.com/site/devkorsakov/files/android_pdf_export.zip?attredirects=0&d=1

かんたん家計簿 ヘルプ&不具合報告掲示板



Androidアプリ「かんたん家計簿」について分らないことや、
不具合を報告していただく掲示板です。
不具合だけでなく、ちょっとした改善要望も気軽に投稿して頂けます。


不具合を報告していただく際は、ご利用の端末、OSバージョンなども一緒に記載してください。




今後のアップデート予定。

機能の改善・追加
クレジット管理機能の追加実装
DropBoxとの連携(Proで実装予定)
不具合の修正
特定の機種でのみ、残高の計算が正常に行われない問題
(XperiaAcroでのみ報告を受けております。しかしながら当方もXperiaAcroにて運用しておりますが、まだ一度も残高のズレる不具合は発生しておりません・・・端末その物の不具合か、もしくは他のアプリケーションが関連しているのか不明です。
引き続き調査します)




ヘルプ一覧

基本残高は一度設定すると変更できないのでしょうか?

基本設定ボタンから基本残高を変更する事が可能です。


基本残高とは何ですか?

基本残高は一番最初に入力する金額で、例えば銀行口座の残高や、お財布に入ってる金額を入力します。そうすることで、家計簿をつけた直後から財布等の残金を把握することが出来ます。


お給料などの収入はどうやってつければ良いですか?

お給料などの収入については、家計簿を作成する際「支出・収入」の項目を「収入」に合わせて頂き、金額を入力して確定すると、家計簿に収入項目として登録され、残高が増えます。


データがいきなり消えたりしませんか?

自動バックアップ機能と、自動リストア機能がついておりますので、万が一データが消えても、即座に復元されます。


月の締め日を月によって変えることはできないでしょうか?

出来ません。それをすると、月によって日数が余計に増えたり減ったりするため、正確に収支を算出することが難しくなります。例え締め日が休日の時でも、それを家計簿に記録する上で問題はありません。


残高の表示が狂う。項目の金額が合わない。削除すると金額が狂う。

設定画面よりデータベースの修復を実行することで解決します。原因はAndroidのそのものです。メモリが少ないなどが原因でシステムそのものが不安定な場合は、データを記録するときにシステムが干渉したりすると正確にデータを記録することができないと考えられます。


パスコードロック機能はついてないのですか?

有料版についております。長く使っていただけるようでしたら、是非お買い求めください。