パークのソフトウエア開発者ブログ|ICT技術(Java・Android・iPhone・C・Ruby)なら株式会社パークにお任せください -27ページ目

パークのソフトウエア開発者ブログ|ICT技術(Java・Android・iPhone・C・Ruby)なら株式会社パークにお任せください

開発の解決方法や新しい手法の情報を、パークのエンジニアが提供します。パークのエンジニアが必要な場合は、ぜひお気軽にお問い合わせ下さい。 株式会社パーク:http://www.pa-rk.co.jp/

こんにちは、中村です。
今回はGradleとAndroidのお話をしたいと思います。

さて、Android Studio、Android開発者の間では話題になってますよね。
ゆんぼうの記事にも概要やインストール方法などが載ってるので、その部分はそちらを参照してください。

正直私は見た目があんまり好みじゃなくてEclipseを使い続けてたんですが、Gradleの魅力を知ってからAndroid Studioにも慣れとかなきゃいけないかなあという気持ちになっております。
というのは、Gradleのandroidプラグインの中にProduct flavorsという機能がありまして、その機能をフルに使うためにはやっぱりEclipseだと限界があるのかなと思い始めまして。

いきなりGradleやらProduct flavorsやら、あんまり聞かない単語が続いたと思うので、ここでこの2つの技術を簡単に説明したいと思います。
  • Gradle
  • 簡単に言うと、Antの発展版というところでしょうか。
    中身の設定ファイル(build.gradle)をGroovyというプログラム言語で書けるので、設定ファイルをXMLで書くAntよりも柔軟なことが簡単にできちゃいます。
  • Product flavors
  • 上に書いたように、gradleのandroidプラグインが提供する機能の1つです。
    一言で言うと、同じようなアプリでリソースや実装の違いを同じプロジェクト配下で管理できる方法を提供する機能ということになります。
    例えば無料版と有料版で、広告の有無のようなリソースの差分、有料版で機能を豊富にするためのソースコードを切り替える場合です。
    従来だと、プロジェクトを分けたりバージョン管理上のブランチで管理したりといった煩雑な方法でしか管理ができませんでした。
    それを1つのプロジェクト内でビルドするソースコードやリソースを切り替える機能を提供し、煩雑な管理を省いてくれるのがProduct flavorsです。
と。説明はここまでにして、ここからはEclipseで作ったプロジェクトをAndroid StudioにインポートしてProduct flavorsで複数のapkファイルをビルドして動かすまでの手順を書いていきたいと思います。
今回使ったツールのバージョンは以下のようになります。
  • Eclipse: Kepler
  • Android Studio: 0.4.0
  • JDK: OracleJDK 1.6.0 u37 64bit
  • Android SDK: 22.3
  • Gradle: 1.9
  • Gradle Android plugin: 0.7

まずは[android_sample]という名前でEclipseで簡単なプロジェクトを作成します。



このプロジェクトをAndroid Studioでインポートします。


インポートの結果はプロジェクト直下にできた[import-summary.txt]に書かれています。
ここに書かれている通り、プロジェクト配下のディレクトリ構成やAndroid Manifest.xmlの場所が変更になってますね。
それと、ビルドシステムがGradleベースになってるので、[build.gradle]などのgradleのビルドに必要なファイルが配置されています。

さて、ここからはProduct flavorsを使い始めてみようと思います。
まずは[app/build.gradle]のandroid配下を編集してFlavorを追加します。
ここでは[pro]版と[free]版を用意して、ついでにそれぞれのパッケージ名を変えて2つのアプリが1つのデバイス中で共存できるようにしてみます。
このパッケージ名はAndroidManifest.xmlに書かれるもので、実際のソースファイルのものではありません。
android {
    // 一番最後に以下を追加します
    productFlavors {
        pro {
            packageName "com.example.android_sample.pro"
        }
        free {
            packageName "com.example.android_sample.free"
        }
    }
}
ファイルの編集後、Android Studioの[Tools]→[Android]→[Sync Project With Gradle Files]を選択するとAndroid StudioにFlavorの追加が認識されます。

せっかくなのでソースコードとリソースの切り替えもやってみましょう。
今回はMainActivityと同階層にFooクラスを作って、そのメソッドをMainActivityからコールするコードを書いてみます。
この呼び出すFooクラスをFlavorでのソース切り替え対象にすることにします。
また、リソース切り替え対象はstrings.xmlを使い、アプリ名や画面上のメッセージの切り替えてみようと思います。
それぞれのファイルの内容は以下のようにします。
package com.example.android_sample;

import android.app.Activity;
import android.os.Bundle;

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

        Foo.saySomething(this);
    }
}
package com.example.android_sample;

import android.content.Context;
import android.widget.Toast;

public class Foo {
    public static void saySomething(Context context) {
        Toast.makeText(context, "This is pro version", Toast.LENGTH_SHORT).show();
    }
}

package com.example.android_sample;

import android.content.Context;
import android.widget.Toast;

public class Foo {
    public static void saySomething(Context context) {
        Toast.makeText(context, "This is free version", Toast.LENGTH_SHORT).show();
    }
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">android_sample (pro)</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello pro world!</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">android_sample(free)</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello free world!</string>
</resources>
ディレクトリ構成は以下の通りです。
(今回の切り替え対象やアプリ上の表示関係のないファイルは省略しています)
リソースファイルはmainと他Flavorで重複してもFlavorのもので上書きしてくれるんですが、ソースファイルの方では重複するとビルド時にエラーになるので注意が必要です。
android_sample (root)
`-- app
  `-- src
    |-- free
    | |-- java
    | | `-- com
    | |   `-- example
    | |     `-- android_sample
    | |       `-- Foo.java
    | `-- res
    |   `-- values
    |     `-- strings.xml
    |-- main
    | |-- assets
    | |-- java
    | | `-- com
    | |   `-- example
    | |     `-- android_sample
    | |       `-- MainActivity.java
    | |-- res
    | |   |-- layout
    | |   | `-- activity_main.xml
    | |   `-- values
    | |     `-- strings.xml
    | `-- AndroidManifest.xml
    `-- pro
        |-- java
        | `-- com
        |   `--example
        |     `-- android_sample
        |       `-- Foo.java
        `-- res
          `-- values
            `-- strings.xml
ファイルの編集が終わったら、Android Projectの左下にいる[Build Valiant]を選択して、Flavorの切り替えをしてみましょう。
以下の画像のようにapp/src/pro/javaとapp/src/free/javaの配下がJavaのソースセットとして切り替わるのがわかると思います。


それぞれのFlavorで[Build]→[Make Project]でビルドをしてみると、app/build/apk配下にそれぞれのapkファイルができていると思います。
この2つのapkファイルをデバイスにインストールしてみると、パッケージが異なるので以下の画像のように2つのアプリが共存ができるようになります。
作成したアプリは画像中のandroid_sample(pro)とandroid_sample(free)になります。

それぞれのアプリを起動して、振る舞いの違いも見てみましょう。
Pro版、Free版で表示されるメッセージとToastで表示されているメッセージが切り替わっているのがわかると思います。


さて、最後にまとめとして、今回は同じアプリの実装やリソースをFlavorとして切り替える方法を紹介しました。

やっぱりAndroid StudioはビルドシステムとしてGradleを採用しているだけあって、Flavorでの切り替えがスムーズにできますね。
Eclipseでも[外部ツール]としてGradleを使ってある程度のことはできるんですが、ソースセットの切り替えの部分というのがAndroid Studioのように簡単にはできませんでした。
(本当はこのブログ内でEclipseでFlavorを切り替える方法を紹介したかったんですが...)
まあ、ここらへんはEclipseのAndroidSDKToolsがプラグインだということもあって、なかなか難しいのかなと思います。

では、今回はここらへんで。
このブログの執筆時点でもう2013年も終わりに近くなってまいりました。皆さん、良いお年を~。
Asteriskのインストールから設定までお世話になったサイトまとめです。

インストールは比較的に簡単に行えました。
内線として利用するまでは、「Asterisk基本設定ガイド!」が参考になりました。
※バージョンによっては設定ファイルの記述方式が違うようですね。

-----------------------------------------------------------
■asteriskサイト
-----------------------------------------------------------
http://www.asterisk.org/

-----------------------------------------------------------
■asteriskとは?
-----------------------------------------------------------
@IT
http://www.atmarkit.co.jp/fnetwork/rensai/asterisk/01/01.html

ITpro
http://itpro.nikkeibp.co.jp/article/COLUMN/20060330/233889/

-----------------------------------------------------------
■設定関連
-----------------------------------------------------------
Asterisk基本設定ガイド!
http://www.st-asterisk.com/
→内線設定関連でお世話になりました。

ソフトフォン設定
http://www.st-asterisk.com/archives/46

やまさんノート
http://yama30501.blog137.fc2.com/blog-entry-154.html
→インストール関連でお世話になりました。
※失敗事例まで説明にはいっているため、罠ありです。

■製品比較
----------------------------------------------------------
■NTT SOFTのAsteriskソリューション
「Asterisk Business EditionTM」はオープンソース版「Asterisk(R)」と異なり、以下のようなメリットがあります。
 提供元Digium社による動作確認及び保証/サポートつき
 ソースコードを改変する際に守秘情報を含むコードを非公開にできる
電話会議システム
http://www.ntts.co.jp/products/asterisk/adjust_02.html
コールセンター
http://www.ntts.co.jp/products/asterisk/adjust_01.html


■株式会社and One
シンプルなUI
http://www.andone.co.jp/primus/asterisk/

----------------------------------------------------------

こんにちは。ゆんぼう です。
今回は、CoreDataについて紹介します。

CoreData は、メモリ上のオブジェクトをリレーショナルデータベースである SQLite のレコードに変換して保存、または、その逆にレコードをオブジェクトに変換してメモリ展開するフレームワークです。レコードとオブジェクトの変換を行うフレームワークのことをO/R マッピングフレームワークと呼びます。

では、実際にCoreDataを使用して、データベースにアクセスするiPhoneアプリを作成したいと思います。

今回の開発環境は以下の通りです。
・OS X v10.9
・Xcode v5.0.2

まず、Xcodeでプロジェクトを作成します。
Xcodeを起動します。



「Choose a template for your new project」画面で
「Empty Application」を選択します。
「Next」ボタンを押下します。



「Choose options for your new project」画面で
「Product Name」にプロジェクト名を入力します。
「Use Core Data」にチェックをいれます。
「Next」ボタンを押下します。



先ほどの「Use Core Data」を選択して、プロジェクトを作成すると、
「coreDataSample1.xcdatamodeld」が作成されています。
Xcodeのファイル一覧画面で「coreDataSample1.xcdatamodeld」を選択します。



「Add Entity」を選択すると、新しくEntityが追加されます。データベースのテーブルの部分になります。

ここでは、「SampleEntity」と入力します。
ENTITIESの「SampleEntity」を選択します。



「Add Attribute」を選択すると、新しくAttributeが追加されます。データベースのカラムの部分になります。
「Attribute」がカラム名、「Type」がカラムの型となります。
ここでは、「name」及び「age」を入力します。



プロジェクトで右クリックして、新しくファイルを作成します。
「CoreData」から「NSManagedObject」を選択します。
「Next」を押下します。



データモデルを選択します。
「Next」を押下します。



Entityを選択します。
「Next」を押下します。完了すると、自動的に「SampleEntity.h」「SampleEntity.m」ファイルが生成されます。

次に、DAOを作成します。
DAOとは、Data Access Objectの略です。
データベースを操作するインタフェースを提供するオブジェクトになります。

Xcodeのプロジェクトを右クリックして[New File...]を選択します。
Choose a template for your new file画面で[Cocoa Touch]->[Objective-C class]を選択します。
以下の値を入力して、DAOクラスを作成します。
・Class: SampleEntityDAO
・Subclass of: NSObject

- (void)setSampleEntityName:(NSString *)name age:(NSNumber *)age
{
AppDelegate *appDeletage = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *managedObjectContext = [appDeletage managedObjectContext];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entityDes = [NSEntityDescription entityForName:@"SampleEntity" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityDes];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", name];
[fetchRequest setPredicate:predicate];

NSError *error = nil;
NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if(nil != error){
NSLog(@"SampleEntityDAO#setSampleEntityList error %@, %@", error, [error userInfo]);
}

int resultCnt = [result count];
if(0 == resultCnt){
SampleEntity *item = [NSEntityDescription insertNewObjectForEntityForName:@"SampleEntity" inManagedObjectContext:managedObjectContext];
item.name = name;
item.age = age;
} else {
SampleEntity *item = [result objectAtIndex:0];
item.age = age;
}

BOOL ret = [managedObjectContext save:&error];
if(!ret){
NSLog(@"SampleEntityDAO#setSampleEntityList error %@, %@", error, [error userInfo]);
}
}

NSEntityDescriptionクラスで、SampleEntityのエンティティ情報を取得しています。NSPredicateクラスで、「name」のAttributeと一致しているレコードを検索しています。検索の結果、一致しなければ(0 == resultCnt)レコードをInsertしており、一致していれば「age」の値を更新しています。

- (NSArray *)getSampleEntityItemList
{
AppDelegate *appDeletage = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *managedObjectContext = [appDeletage managedObjectContext];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entityDes;

entityDes = [NSEntityDescription entityForName:@"SampleEntity" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityDes];

NSSortDescriptor *sortDes = [[NSSortDescriptor alloc]initWithKey:@"age" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDes, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

NSError *error = nil;
NSArray *itemList = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if(nil != error){
NSLog(@"SampleEntityDAO#getSampleEntityItemList error %@, %@", error, [error userInfo]);
}
return itemList;
}

NSSortDescriptorクラスで、「age」のAttributeで昇順にソートを行っています。

DAOの呼び出し部分を作成します。
DAOを使いたいクラスで記述してください。

SampleEntityDAO *dao = [[SampleEntityDAO alloc]init];
[dao setSampleEntityName:@"ゆんぼう" age:[NSNumber numberWithInt:17]];
[dao setSampleEntityName:@"たけぼう" age:[NSNumber numberWithInt:28]];
[dao setSampleEntityName:@"しおぼう" age:[NSNumber numberWithInt:40]];
[dao setSampleEntityName:@"あさぼう" age:[NSNumber numberWithInt:29]];

NSArray *itemList = [dao getSampleEntityItemList];
for(SampleEntity *item in itemList) {
NSLog(@"name:%@, age:%@",item.name, item.age);
}

setSampleEntityName でデータベースにデータを保存して、getSampleEntityItemList でデータベースからデータを読み出しています。
実行すると下記の内容になります。

出力結果
name:ゆんぼう, age:17
name:たけぼう, age:28
name:あさぼう, age:29
name:しおぼう, age:40

以上です。
こんにちは。バグ太郎です。

いつぞや投稿致しました記事に影響された方がいると信じて
fenrirに関連する記事を書かせて頂きます。

さて、fenrirといえば私が褒めに褒めちぎった高機能ファイランチャーですが
まずは利点をおさらいしてみましょう。

【利点】
・ファイラー+ランチャー、あるいはランチャーとして使える。
・インデックスを用いたディレクトリ探索機能がある。
・履歴から候補ディレクトリの表示順が変わる。
・レジストリを弄らず、設定は.iniのみ。
・キーワード、コマンドを自己で設定できる。
・動作がとても軽い。
・これと高機能なファイラーをあわせることでデスクトップを汚すことがなくなる。

以上のようになります。
前回は利点をあげるばかりだったので、
今回は私の体験談から問題点と打開策を提案させて頂きます。

・キーワード、コマンドを自己で設定できる。

というのが利点でも挙げられましたが、実は私がfenrirを使い始めた頃

「キーワードを設定しすぎて覚えられなかった。」んです。

いや、fenrir自体の問題点でも欠点でもなんでもないんですが・・・。
調子に乗りすぎて一気にコマンドを設定したとき

(あれ、設定したアレを起動するキーワードなんだったっけかな・・・)
って具合に、ちょこちょこfenrirの「instant.ini」を見に行ってました。

効率をあげるつもりだったのに。

というわけでhelpを作りましょう。
helpなんて言ってもキーワードを確認するんですから、コマンドを設定している「instant.ini」を表示すればいいだけですね。

今回はJScriptを使ってみました。
テキトーにテキスト作って以下を記述、拡張子を「.js」にします。

var FSO = new ActiveXObject("Scripting.FileSystemObject");
var path = "C:\\foo\\bar\\hoge\\instant.ini";
var stream = FSO.OpenTextFile(path, 1);
WScript.Echo(stream.ReadAll());
stream.Close();

pathの部分は確認したい「instant.ini」がある場所を指定してください。
「instant.ini」側に以下を記述します。キーワードはhelpでもなんでもお好きなようにどうぞ。

help=""%cmddir\instant.js" "%A""

ちなみに%cmddirというのは使用しているfenrirの下階層「cmd」ディレクトリを指します。
先ほど作成した「instant.js」を「cmd」ディレクトリにぶち込めばいいわけですね。

また、先ほど作成した内容だと「instant.ini」の内容は全て出力されてしまいます。
コメントの表示とかいらねーよ!という方は以下のような記述になると思います。

var FSO = new ActiveXObject("Scripting.FileSystemObject");
var path = "C:\\foo\\bar\\hoge\\instant.ini";
var stream = FSO.OpenTextFile(path, 1);
res = stream.ReadAll();
res = res.replace(/;.*$\n/gm,"");
WScript.Echo(res);
stream.Close();

後は好きなだけ「instant.ini」を肥大化させてしまっても
設定を忘れたときには「fenrirさん助けてー!」とinstant.jsを呼び出せば良いということですね。

好きなだけ設定して遊んでください。

Σ(゚д゚lll)ガーン
あれれ?もう12月!?
1年経つの早すぎじゃないですか?

というわけで、今回は年にまつわる問題の紹介です。


Y2K問題(2000年問題)
2000年になることで西暦を下2桁で管理するシステムが誤動作を引き起こすとされた問題。
  • 西暦が99→00となるため日時でソートしているシステムで誤動作が起こる
  • C言語tm構造体の年は1900年からの年数だが、2000年には3桁の100になるため表示その他での問題
  • 2000年は閏年だがこれに対応していないシステムが少なくなかった
  • 当時は世界中のシステムが誤動作して核ミサイルが飛び交うような怖いことも囁かれてた((((;゜Д゜)))))))

個人的には担当システムを調査した際に「エラーログのタイムスタンプが100年になるけど修正しますか~?」ってレベルしかなくて拍子抜けした思い出しかありません。
今思うと当時はY2K問題への対策特需で業界も潤ってて良かったんじゃないかと思ったり

2019年問題
GPS衛星に搭載されている時計の10bitの積算週が2019年4月7日に0にリセットされる、これは問題というよりGPSの仕様。
  • 1999年8月21日に同様の事象でカーナビに問題が発生しているが、二度目の2019年はさすがに大丈夫との声もある
  • GPS搭載機器の製品数や普及台数は1999年当時とは比較にならないため、はたしてどうなるか?


2025年問題
日本の元号が昭和換算で100年になることで起こりうる問題。
  • 官公庁では年を昭和換算の元号で扱っているシステムが少なくない模様


2036年問題
基準時間が1900年1月1日で経過秒数を符号無し32bit整数値で管理しているシステムが2036年2月7日6時28分15秒に桁あふれしてしまう問題。
  • 時刻を同期するために用いられるNTPプロトコルは桁あふれ後(最上位bit0の場合)は起点を2036年2月7日6時28分16秒に変えて解釈することで回避予定
  • 古いWindowsOSも同様の問題が存在するがその頃には使用されていないので問題とはならない模様


2038年問題
1970年1月1日からの経過秒数であるUNIX時間が2038年1月19日3時14分7秒に桁あふれする問題。
  • 日時(time_t型)を符号付き32bit整数値(=31bit)として扱っているシステムで誤動作が起こりうる
  • C言語の問題でもあるので影響はUNIX系OSだけとは限らない
  • ファイルシステムでも更新日時を32bit値で保管しているものがあり、プログラムのリビルドだけでは済まない可能性が高い
  • Y2K問題と異なり中途半端な年月日なため、業界関係者以外の理解や周知が難しいとの指摘がある

あと20年以上あるのでなんとかなるでしょう(^人^)

Y10K問題
西暦10000年になると5桁になるけど大丈夫か?という問題w
エイプリルフールネタのRFCもあります:-)