raspberry Piの日本語化

raspberry Piの日本語化

raspberry piは最初は日本語環境がないため
日本語フォント
日本語入力メソッド
をインストールする必要がある

まず、電源を入れて

pi

とユーザー名を入れて、パスワード入力

ログインできたら

sudo raspi-config

で設定画面を表示

ここで、
Internationalisation Options >
Change Locale
で表示される画面で

ja_JP .EUC-JP EUC-JP

ja_JP .UTF-8 UTF-8
にチェックがついているのを確認

これで、okを押すと次の画面で
デフォルト言語を聞かれるので
en_GB.UTF-8
から
ja_JP.UTF-8
へ変更する

言語設定には時間がかかるため、気長に待つ

変更が適用されると
設定画面のトップページの
Setup Options
の画面になるので、Finishを選択して終了する

言語設定はできたので
次に、日本語表示に必要な日本語フォントをインストール

sudo apt-get install ttf-kochi-gothic xfonts-intl-Japanese xfonts-intl-Japanese-big xfonts-kaname

次に、日本語入力メソッドをインストール
日本語入力メソッドは、ATOKとかみたいに、日本語を入力するためのソフト

sudo apt-get install uim uim-anthy

これで、デスクトップ環境では日本語が使えるようになるけど
今度は、端末画面が文字化けする

なので、対策としてjfbterm をインストールする

sudo apt-get install jfbterm

これで準備できたので、設定反映のため、シェルにログインしなおす
つまり、一度ログアウトして、再度ログインする

再度ログインすると、設定が有効になりデフォルト言語が日本語化する
ただし、文字化けするため

jfbterm

で切り替える必要がある

日本語ではなく英語にしたいというのなら

export LANG=en

とすればログアウトするまで英語設定になる

長押しの検出

長押しの検出

長押しの検出は、onLongPress()で処理を記述する

ガラケーのボタン押しっぱなし処理のようなものを作るときとかの実装に使えそう

まず、

implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener

を追加

そして、アクセスしやすいように、メンバ変数の宣言

GestureDetector mGestureDetector;

次に、onCreate()の中でインスタンス作成

mGestureDetector = new GestureDetector(this,this);

次に、タッチイベント実装
ここで、タッチイベントの判別振り分けをする

public boolean onTouchEvent(MotionEvent e){
mGestureDetector.onTouchEvent(e);
return false;
}

そして、それぞれのタッチイベントを定義する
今回は、長押しのときだけ検出するので
onLongPress()のときに
トーストで表示

public boolean onLongPress(MotionEvent e){
Toast.makeText(this, "長押し検出しました",Toast.LENGTH_SHORT).show();
return false;
}

これで、画面長押しすると、トーストで表示される

ちなみに、他の動作をメモると

//シングルタップ
@Override
public boolean onSingleTapUp(MotionEvent e){
return false;
}

//ダブルタップ
public boolean onDoubleTap(MotionEvent e){
return false;
}

//画面を押したとき
public boolean onDown(MotionEvent e){
return false;
}

//スワイプ
@Override
public boolean onFing(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
return false;
}

//スクロール
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY){
return false;
}

スワイプの検出

スワイプの検出

スワイプの検出は
MotionEventを定義すれば実装できる

まず、定数を宣言

private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;

private GestureDetector mGestureDetector;

次に、onCreate()の中でインスタンス取得

mGestureDetector = new GestureDetector(this, mOnGestureListener);

この
mOnGestureListenerは後で作成

次に、onTouchEvent()の実装

@Override
public boolean onTouchEvent(MotionEvent e){

return mGestureDetector.onTouchEvent(e);
}

そして、スワイプ動作の検出
これは、onFing()の中で処理すればいい

private final SimpleOnGestureListener mOnGestureListener = new SimpleOnGestureListener(){

@Override
public boolean onFing(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY){

try{

if(Math.abs(event1.getY() - event2.getY()) < SWIPE_MAX_OFF_PATH){
return false;
}
if(event1.getX() - event2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
Toast.makeText(MainActivity.this, "左スワイプ", Toast.LENGTH_SHORT).show();
}
else if(event2.getX() - event1.getX() > SWIPE_MIN_DISTANCE && Math.abs()velocityX > SWIPE_THRESHOLD_VELOCITY){

Toast.makeText(MainActivity.this, "右スワイプ", Toast.LENGTH_SHORT).show();
}
}catch(Exception e){
//nothing
}

}
return false;
}
};

このように、定数で座標を設定し、それに対する範囲の判定をすることで
スワイプのときの動作をすることができる

raspberry Pi設定

前回、raspberry Piのインストールができたので

今回はIpアドレスの確認とソフトウェアのインストール

まず、raspberry  PiをLANケーブルにつないだ状態で電源を入れる

すると、サーバーみたいな画面になるので

ユーザー名 piを入れ

パスワードを入れてログイン

IPアドレスを調べたいので

hostname -I

でIPを確認

もし、ネットワーク全体を調べたいのなら

ifconfig

で表示できる

ソフトウェアのインストールは

ubuntu と同じように

sudo apt-get install パッケージ名

でインストールできる

今回は、Linuxではおなじみのテキストエディタ vim をインストールするので

sudo apt-get install vim 

ちなみに、アップデートも ubuntuと同じように

sudo apt-get update

でパッケージリストを更新して

sudo apt-get upgrade

でパッケージ更新

ちなみに、アンインストールしたいときには

sudo apt-get autoremove パッケージ名

で依存するパッケージごと削除できる

単純に、指定したものだけ削除するなら

sudo apt-get remove パッケージ名

とすればいい

画面回転の検出

画面回転の検出

画面回転の検出は
Configurationクラスの
orientation変数を使う

値が
ORIENTATION_LANDSCAPEなら横

ORIENTATION_PORTRAITなら縦になる

判定はif()などで行う

例えば、縦、横に回転したときに
トーストで表示するのなら

if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
Toast.makeText(this, "横になったよ", Toast.LENGTH_SHORT).show();
}
else if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this,"縦になったよ", Toast.LENGTH_SHORT).show();
}

これで、縦、横の画面回転の検出ができる

タップ、ダブルタップの検出

タップ、ダブルタップの検出

タップやダブルタップの検出は
GestureDetectorと
onTouchEventを設定すれば実装できる

まず、

implements GestureDetector.OnGestureDetector, GestureDetector.OnDoubleTapListener

を追加

そして

GestureDetector mGestureDetector;

でメンバ変数宣言

次に、onCreate()の中で

mGestureDetector = new GestureDetector(this, this);

でGestureDetectorインスタンス作成

次に、タッチイベント実装

public boolean onTouchEvent(MotionEvent e){

//GestureDetector.onTouchEvent()でタッチイベントの判別、振り分けをする
mGestureDetector.onTouchEvent(e);

return false;
}

次に、シングルタップの実装
今回、はシングルタップならトーストで表示

@Override
public boolean onSingleTapUp(MotionEvent e){

Toast.makeText(this, 
"シングルタップだよ",Toast.LENGTH_SHORT).show();
return false;
}

そして、ダブルタップの処理
今回は、ダブルタップを検出したらトーストで表示

public boolean onDoubleTap(MotionEvent e){

Toast.makeText(this,"ダブルタップされたよ",Toast.LENGTH_SHORT).show();
return false;
}

タップの検出だけなら
ViewへonTouchListenerの設定だけでよい
しかし、ダブルタップとシングルタップを検出するのなら
GestureDetectorを使う

GestureDetectorは、
シングルタップ
ダブルタップ以外に、スワイプなども検出できる

ローダーの作成

ローダーの作成

ローダーを使うには、
FragmentActivityクラスのサブクラスを作成する

ローダーとは、ActivityやFragmentで
非同期にデータをロードする仕組みのこと
データを監視して、コンテンツが変化したら新しい結果を返す
WebでAjaxとかやってるとイメージしやすい

今回は、非同期でブックマーク履歴を読み込んで表示

ブックマークの取得には権限が必要
この権限は
READ_HISTORY_BOOKMARKS
になるので、
AndroidManifest.xmlへ権限を追記する

<uses-permission 
android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>

を追加

次に、レイアウトファイルの作成

<RelativeLayout
xmlns:android="http://schemes.android.com/apk/res/android"
xmlns:tools="http://schemes.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true">
</ListView>

</RelativeLayout>

次に、FragmentActivityクラスのサブクラスを作成し
LoaderCallbacksインターフェースを実装する

onCreate()をOverrideして
ListViewクラスを生成し
Adapterの指定とローダーの初期化をする

それから、LoaderCallbacksインターフェースの実装となる

これには
onCreateLoader()
onLoadFinished()
onLoadReset()
を使う

まずは、メンバ変数の定義

private SimpleCursorAdapter adapter;

次に、onCreate()のOverride

@Override
protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);
setContentView(R.layout.main);

adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
null,
new String[]{Browser.BookmarkColumns.TITLE},
new int[] {android.R.id.text}
,0);

ListView listview = (ListView)findViewById(R.id.list);
listview.setAdapter(adapter);

getSupportLoaderManager().initLoader(0,savedInstanceState,this);
}

次に、onCreateLoader()の実装

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args){

return new CursorLoader(this,Browser.BOOKMARKS_URI,null,null,null,null );
}

そして、onLoadFinished()の実装

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor){
adapter.SwapCursor(cursor);
}

そして、onLoadReset()の実装

@Override
public void onLoadReset(Loader<Cursor> loader){
adapter.setCursor(null);
}

今回、LoaderCallbacksインターフェースの
onCreateLoader()では
Browser.BOOKMARKS_URIで
ブックマークのURIを指定してるけど
電話帳などの
ContentProviderのURIの指定もできる

DialogFragmentの作成

DialogFragmentの作成

DialogFragmentクラスを使ってダイアログを作成するには
FragmentActivityのサブクラスを作成する

まず、Javaで、FragmentActivityクラスのサブクラスを作成

onCreate()の中で
MyDialogFragmentクラスの生成、表示を実装

extends FragmentActivity

で継承しておく

次に、onCreate()の追加部分

//DialogFragment表示
FragmentManager manager = getSupportFragmentManager();

MyDialogFragment dialog = (MyDialogFragment)manager.findFragmentByTag("tag");

if(dialog == null){

dialog = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("message","Message");

dialog.setArguments(args);
dialog.show(manager, "tag");
}

次に、DialogFragmentのサブクラス作成

onCreateDialog()へダイアログの生成

onClick()へ
ok キャンセルボタンを押したときの処理を実装

このクラスでは

extends DialogFragment implements DialogInterface.OnClickListener

で継承しておく

まずは、onCreateDialog()の実装

@Override
public void onCreateDialog(Bundle savedInstanceState){

//値の取得
String message = getArguments().getString("message");

return new AlertDialog.Builder(getActivity()).

//タイトル設定
setTitle("Title")

//メッセージ設定
.setMessage(message)

//okボタンの設定
.setPositiveButton("ok",this)

//cancelボタンの設定
.setNegativeButton("cancel",this)

.create();
}

そして、ボタンクリックしたときの設定
switchで分岐させれるので、okとcancelの処理を
onClick()の中へかける

@Override
public void onClick(DialogInstance dialog, int which){

switch(which){

//okボタンクリックの場合
case AlertDialog.BUTTON_POSITIVE:
Toast.makeText(getActivity(), "ok", Toast.LENGTH_SHORT).show();
break;

//cancelボタンクリックの場合
case AlertDialog.BUTTON_NEGATIVE:
Toast.makeText(getActivity(), "cancel",Toast.LENGTH_SHORT).show();
break;
}
}

FragmentDialogに対して
setArguments()を使って値を渡しているのは
コンストラクタで値を渡すと
ダイアログが生成されるタイミングで値が破棄されることがあるから

Fragmentの作成

Fragmentの作成

Fragmentを使った画面の作成は
FragmentActivityのサブクラスを作成してから
Fragmentの生成、追加をする

Fragmentは、Activityへ配置する部品で
複数のFragmentの配置ができる

Fragmentは自分自身のライフサイクルを持つため
イベント処理、Activityの実行中でも追加、削除が可能

Fragmentのライフサイクルは
Activityのライフサイクルと連動しているので
Activityが休止状態になると
Fragmentも休止状態になる

また、Activityが破棄されるとFragmentも破棄される

まずは、FragmentActivityのサブクラスの作成

public class Fragment extends FragmentActivity implements onClickListener{

}

次に、FragmentのレイアウトファイルをXMLで作成

<LinearLayout
 xmlns:android="http://schemes.android.com/apk/res/android"

android:id="@+id/myfragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>

次に、JavaでFragmentのためのサブクラスを作成する
これには、レイアウトファイルをロードして生成する

extends Fragment

でFragmentを使えるようにする

今回は、動的にViewを追加する

@Override
public View onCreateView(LayoutInflater inflater , ViewGroup container, Bundle savedInstanceState){

return inflater.Inflate(R.layout.fragment, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState){

super.onViewCreate(view, savedInstanceState);

TextView text = (TextView)findViewById(R.id.text);
text.setGravity(Gravity.CENTER);
text.setText(getArguments().getString(“value”));
}

[/java]

次に、Fragmentを動的に追加する
onClick()をOverrideして
追加ボタンを押したタイミングで
Fragmentクラスを追加、更新する

@Override
public void onClick(View v){

FragmentManager manager = getSupportFragmentManager();
Fragment fragment = manager.findFragmentById(R.id.parent);

if(R.id.btn_add_code == v.getId() || R.id.btn_add_xml == v.getId()){

if(fragment == null){

FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.parent, getMyFragment(v.getId(), true), "MyFragment");

transaction.commit();

}else{
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.parent, getMyFragment(v.getId(), false));
transaction.commit();

}
}else if(R.id.btn_remove == v.getId() && fragment. != null){
FragmentTransaction transaction = manager.beginTransaction();
transaction.remove(fragment);
transaction.commit();
}
}

Fragmentの追加、更新には
FragmentManagerクラスの
beginTransaction()を使うことで
トランザクションを開始する

そして、次に追加、更新、削除した後に
commit()で、トランザクションをコミットする

FragmentManagerクラスの
findFragmentById()で
生成済みのFragmentが取得できないのなら
add()で、Fragmentを追加すればいい

Fragmentが生成済みなら
replace()でFragmentを更新できる

ActivityとServiceの連携

ActivityとServiceの連携

Activityと
Android Interface Definition Language
(AIDL)
を使ったサービスで連携できる

実装するには、まずAIDLインターフェースを定義する

srcフォルダの直下へ
拡張子 .aidlファイル作成

ソースは

package net.developapp.activityservice;

interface ActivityService{
int addString(String value);
String getString();
}

次に、サービス作成

ここではonBind()の実装
.Stubインターフェースの実装をする

@Override
public void onBind(Intent arg0){
return mBinder;
}

//AIDL Binder実装
private ActivityService.Stub Binder = new ActivityService.Stub(){

@Override
public int addString(String value) throws RemoteException{
mStringList.add(value);
return mStringList.size();
}

@Override
public String[] getString() throws RemoteException{

return mStringList.toArray(new String[mStringList.size()]);
}

};
[/java]

そして、Activityの実装
ここでは
ServiceConnectionの実装
Serviceのbind/unbindを実装をする

まず

extends ListActivity

でListActivityを使えるようにする

private ActivityService mService;

//メンバ変数宣言
private savedConnection

//ServiceConnection実装 mServiceConnection = new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder ibinder){

//ActivityServiceのインターフェース取得
mService = ActivityService.Stub.asInterface(ibinder);

//一覧内容更新
reloadList();
}

public void onServiceDisconnected(ComponentName name){
mService = null;
}
};

次に、onCreate()へ追記
ボタンを押したときの処理をする

findViewById(R.id.buttonadd).setOnClickListener(
new OnClickListener(){

@Override
public void onClick(View v){

EditText editString = (EditText)findViewById(R.id.editText);
if(mService != null){
try{
mService.addString(editText.getText().toString());
reloadList();

}catch(RemoteException e){
e.printStackTrace();
}
}

}
}

);

//ServiceのBind
Intent service = new Intent(this, ServiceActivity.class);
bindService(service, mServiceConnection, BIND_AUTO_CREATE);

次に、onDestroy()の実装

protected void onDestroy(){
super.onDestroy();

//Bind解除
unbindService(mServiceConnection);
}

そして、ユーザー関数reloadList()の実装

private void reloadList(){
try{
//ActivityServiceから文字列のリスト取得
String[] list = mService.getString();

//文字列のリストをListViewへ設定
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R..layout.sample_list_item_1, list);
setListAdapter(adapter);

}catch(RemoteException e){
e.printStackTrace();
}
}

Android Interface Definition Language 通称
AIDLの使いどころは
別アプリから共通処理としてServiceを呼び出したいとき

また、サーバーみたいに同時に複数の呼び出しがあるので
AIDLインターフェースは
完全にスレッドセーフで実装すること