2014年12月23日 星期二
2014年12月22日 星期一
2014年11月24日 星期一
2014年10月8日 星期三
2014年10月7日 星期二
2014年10月5日 星期日
2014年8月20日 星期三
2014年8月12日 星期二
2014年8月11日 星期一
2014年8月10日 星期日
2014年8月7日 星期四
2014年7月31日 星期四
2014年7月13日 星期日
[Android]點選兩次返回鍵離開/關閉程式 範例
分享給大家~
以下使用 @Override onKeyDown 這個事件來做,
一開始 先設定一個flag 用來判斷是否連續按了兩次
接著判斷按下的是哪個按鍵,再來
在 onKeyDown 的 Method 中 使用 Thread 來做 該flag的變更
程式碼如下
還有更多的變化可以使用,比如說變更 Toast 的樣式等...
有賴自己的發揮囉
其他方式:
《Android》實現再按一次返回鍵退出應用程式
以下使用 @Override onKeyDown 這個事件來做,
一開始 先設定一個flag 用來判斷是否連續按了兩次
接著判斷按下的是哪個按鍵,再來
在 onKeyDown 的 Method 中 使用 Thread 來做 該flag的變更
程式碼如下
//判斷離開的flag,設定成全域變數
private boolean is_exit = false;
//點兩次返回鍵離開程式
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
boolean returnValue = false;
if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()==0 && is_exit == false){
Toast.makeText(getBaseContext(), getText(R.string.str_notice_ExitonDoubleKeyDown), Toast.LENGTH_SHORT).show();
is_exit = true;
//一開始 先設定 返回的 flag = true ,若使用者兩秒內沒有動作,則將該 flag 恢復為 false
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
is_exit = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
returnValue = true;
}else{
returnValue = super.onKeyDown(keyCode, event);
}
return returnValue;
}
還有更多的變化可以使用,比如說變更 Toast 的樣式等...
有賴自己的發揮囉
其他方式:
《Android》實現再按一次返回鍵退出應用程式
2014年5月16日 星期五
各廠牌手機工程模式 [Android]
各廠牌手機工程模式:
步驟.1
進入手機撥號介面
步驟.2
輸入以下號碼. (不需要按撥出,按完最後一個碼之後就會進入工程模式了)
HTC => *#*#4636#*#*
Sony => *#*#7378423#*#*
三星 => *#0*#
小米機 => *#*#6484#*#*
華為非 MTK 機種 => *#*#2846579#*#*
華碩 => *#*#4636#*#*
小米 => *#*#6484#*#*
Infocus => *#*#3646633#*#*
LG => 3845#*802#
Acer => *#*#3646633#*#*
NEXUS => *#*#4636#*#*
OPPO => *#*#4636#*#*
一般MTK系列的手機 => *#*#3646633#*#*
提醒 : 進入工程模式後是全英文介面
可以測試螢幕/LED/喇叭/麥克風/相機/WIFI....等等
以上並不保證該廠牌所有型號機種可用,如果不行使用
只好請大家使用谷歌大神囉
步驟.1
進入手機撥號介面
步驟.2
輸入以下號碼. (不需要按撥出,按完最後一個碼之後就會進入工程模式了)
HTC => *#*#4636#*#*
Sony => *#*#7378423#*#*
三星 => *#0*#
小米機 => *#*#6484#*#*
華為非 MTK 機種 => *#*#2846579#*#*
華碩 => *#*#4636#*#*
小米 => *#*#6484#*#*
Infocus => *#*#3646633#*#*
LG => 3845#*802#
Acer => *#*#3646633#*#*
NEXUS => *#*#4636#*#*
OPPO => *#*#4636#*#*
一般MTK系列的手機 => *#*#3646633#*#*
提醒 : 進入工程模式後是全英文介面
可以測試螢幕/LED/喇叭/麥克風/相機/WIFI....等等
以上並不保證該廠牌所有型號機種可用,如果不行使用
只好請大家使用谷歌大神囉
2013年6月23日 星期日
Service BroadcastReceiver Notification 整合應用--在通知列上顯示時間,並常駐!!!
小小的研究心得~分享給大家!!!
程式在按開始後會顯示目前時間及一個計數值,並顯示在通知列上,且通知列上的時間
會持續更新
(顯示計數值是為了確定程式有持續在背景運行)
當使用者按裝置上的Home鍵,程式仍會在背景運行,可點擊通知列上的圖示返回程式
程式畫面:

程式流程:
MainActivity ==> 執行 Service (要執行的動作/運算)
Service ==> 運用 BroadcastReceiver 改變主畫面 UI / 生成 Notification
AndroidManifest.xml 要記得加上 service
程式碼:
=============layout=============
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="39dp"
android:layout_marginTop="28dp"
android:text="開始" />
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/btn_start"
android:layout_alignBottom="@+id/btn_start"
android:layout_centerHorizontal="true"
android:text="結束" />
android:id="@+id/tv_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/btn_start"
android:layout_marginTop="19dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
android:id="@+id/tv_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tv_timer"
android:layout_below="@+id/tv_timer"
android:layout_marginTop="19dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
=============MainActivity.java=============
package com.example.testservice003;
import android.os.Bundle;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.app.NotificationCompat;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
Button start,stop;
TextView show,counter;
static final String ActionFlag = "showtime"; //自訂動作
NotificationManager NM;
Context mContext;
myReceiver mr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button)this.findViewById(R.id.btn_start);
stop = (Button)this.findViewById(R.id.btn_stop);
show = (TextView)this.findViewById(R.id.tv_timer);
counter = (TextView)this.findViewById(R.id.tv_counter);
mContext = this;
//取得NotificationManager
NM = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
//生成 BroadcastReceiver instance
mr = new myReceiver();
//設定自定動作給 Receiver 用
IntentFilter intentFilter = new IntentFilter(ActionFlag);
registerReceiver(mr, intentFilter);
start.setOnClickListener(this);
stop.setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mr); //在Activity 消滅時才unregister
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View v) {
Intent intent = new Intent(getBaseContext(), myService.class);
Bundle bundle = new Bundle();
switch (v.getId()) {
case R.id.btn_start:
//將動作傳給預備回傳資料的 Service
bundle.putString("action", ActionFlag);
intent.putExtras(bundle);
startService(intent);
break;
case R.id.btn_stop:
//將動作傳給預備回傳資料的 Service
bundle.putString("action", ActionFlag);
intent.putExtras(bundle);
stopService(intent);
break;
}
}
class myReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//判斷是否為自訂動作 showtime
if(intent.getAction()==ActionFlag){
//將傳回值塞入View 及 變數中
Bundle bundle = intent.getExtras();
show.setText(bundle.getString("time"));
counter.setText(bundle.getInt("counter")+"");
//取得預備要執行的動作
String action = bundle.getString("action");
if(action.equals("start")){
//準備返回用的Intent
Intent backToMain = new Intent(mContext,MainActivity.class);
//Bundle comebackbundle = new Bundle();
//comebackbundle.putString("comback", "我回來主程式了"); 這個要API Level16 才能用
//PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, backToMain, 0, comebackbundle);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, backToMain, 0);
Notification NF = new NotificationCompat.Builder(mContext)
.setContentTitle("顯示時間") //設定Notification 抬頭
.setContentText(bundle.getString("time")) //設定Notification 顯示內容
.setContentInfo("info訊息") //設定Notification 右方訊息
.setTicker("有時間顯示囉!!") //設定Notification 一開始顯示文字
.setSmallIcon(R.drawable.ic_launcher) //設定Notification 的Icon
.setContentIntent(pendingIntent) //設定Notification 點擊返回的Activity
.setAutoCancel(false) //設定Notification 是否點擊後就消除
.build();
//設定Notification不被清除
NF.flags = Notification.FLAG_NO_CLEAR;
//生成Notification 並給定識別號碼 1
NM.notify(1,NF);
}else{
//取消Notificaiton
NM.cancel(1);
}
}
}
}
}
=============myService.java=============
package com.example.testservice003;
import java.util.Date;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
public class myService extends Service {
Handler handler = new Handler();
String action ="";
int counter;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
//移除Runnable
handler.removeCallbacks(timer);
//準備傳回資料到Receiver,準備關閉Notification
Intent intent = new Intent(action);
Bundle bundle = new Bundle();
bundle.putString("action", "stop");
intent.putExtras(bundle);
sendBroadcast(intent);
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//取得動作
action = intent.getExtras().getString("action");
//每隔一秒執行 timer 的動作
handler.postDelayed(timer, 1000);
return START_NOT_STICKY;
}
Runnable timer = new Runnable() {
@Override
public void run() {
counter++;
sendToReceiver(new Date().toString(), counter);
//每隔一秒重覆執行
handler.postDelayed(this, 1000);
}
};
private void sendToReceiver(String time,int number){
//預備將資料傳回給Receiver,由其來做UI的改變
Intent intent = new Intent(action);
Bundle bundle = new Bundle();
bundle.putString("time", time);
bundle.putInt("counter", number);
bundle.putString("action", "start");
intent.putExtras(bundle);
sendBroadcast(intent);
}
}
程式在按開始後會顯示目前時間及一個計數值,並顯示在通知列上,且通知列上的時間
會持續更新
(顯示計數值是為了確定程式有持續在背景運行)
當使用者按裝置上的Home鍵,程式仍會在背景運行,可點擊通知列上的圖示返回程式
程式畫面:

程式流程:
MainActivity ==> 執行 Service (要執行的動作/運算)
Service ==> 運用 BroadcastReceiver 改變主畫面 UI / 生成 Notification
AndroidManifest.xml 要記得加上 service
程式碼:
=============layout=============
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="39dp"
android:layout_marginTop="28dp"
android:text="開始" />
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/btn_start"
android:layout_alignBottom="@+id/btn_start"
android:layout_centerHorizontal="true"
android:text="結束" />
android:id="@+id/tv_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/btn_start"
android:layout_marginTop="19dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
android:id="@+id/tv_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/tv_timer"
android:layout_below="@+id/tv_timer"
android:layout_marginTop="19dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
=============MainActivity.java=============
package com.example.testservice003;
import android.os.Bundle;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.app.NotificationCompat;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
Button start,stop;
TextView show,counter;
static final String ActionFlag = "showtime"; //自訂動作
NotificationManager NM;
Context mContext;
myReceiver mr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button)this.findViewById(R.id.btn_start);
stop = (Button)this.findViewById(R.id.btn_stop);
show = (TextView)this.findViewById(R.id.tv_timer);
counter = (TextView)this.findViewById(R.id.tv_counter);
mContext = this;
//取得NotificationManager
NM = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
//生成 BroadcastReceiver instance
mr = new myReceiver();
//設定自定動作給 Receiver 用
IntentFilter intentFilter = new IntentFilter(ActionFlag);
registerReceiver(mr, intentFilter);
start.setOnClickListener(this);
stop.setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mr); //在Activity 消滅時才unregister
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View v) {
Intent intent = new Intent(getBaseContext(), myService.class);
Bundle bundle = new Bundle();
switch (v.getId()) {
case R.id.btn_start:
//將動作傳給預備回傳資料的 Service
bundle.putString("action", ActionFlag);
intent.putExtras(bundle);
startService(intent);
break;
case R.id.btn_stop:
//將動作傳給預備回傳資料的 Service
bundle.putString("action", ActionFlag);
intent.putExtras(bundle);
stopService(intent);
break;
}
}
class myReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//判斷是否為自訂動作 showtime
if(intent.getAction()==ActionFlag){
//將傳回值塞入View 及 變數中
Bundle bundle = intent.getExtras();
show.setText(bundle.getString("time"));
counter.setText(bundle.getInt("counter")+"");
//取得預備要執行的動作
String action = bundle.getString("action");
if(action.equals("start")){
//準備返回用的Intent
Intent backToMain = new Intent(mContext,MainActivity.class);
//Bundle comebackbundle = new Bundle();
//comebackbundle.putString("comback", "我回來主程式了"); 這個要API Level16 才能用
//PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, backToMain, 0, comebackbundle);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, backToMain, 0);
Notification NF = new NotificationCompat.Builder(mContext)
.setContentTitle("顯示時間") //設定Notification 抬頭
.setContentText(bundle.getString("time")) //設定Notification 顯示內容
.setContentInfo("info訊息") //設定Notification 右方訊息
.setTicker("有時間顯示囉!!") //設定Notification 一開始顯示文字
.setSmallIcon(R.drawable.ic_launcher) //設定Notification 的Icon
.setContentIntent(pendingIntent) //設定Notification 點擊返回的Activity
.setAutoCancel(false) //設定Notification 是否點擊後就消除
.build();
//設定Notification不被清除
NF.flags = Notification.FLAG_NO_CLEAR;
//生成Notification 並給定識別號碼 1
NM.notify(1,NF);
}else{
//取消Notificaiton
NM.cancel(1);
}
}
}
}
}
package com.example.testservice003;
import java.util.Date;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
public class myService extends Service {
Handler handler = new Handler();
String action ="";
int counter;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
//移除Runnable
handler.removeCallbacks(timer);
//準備傳回資料到Receiver,準備關閉Notification
Intent intent = new Intent(action);
Bundle bundle = new Bundle();
bundle.putString("action", "stop");
intent.putExtras(bundle);
sendBroadcast(intent);
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//取得動作
action = intent.getExtras().getString("action");
//每隔一秒執行 timer 的動作
handler.postDelayed(timer, 1000);
return START_NOT_STICKY;
}
Runnable timer = new Runnable() {
@Override
public void run() {
counter++;
sendToReceiver(new Date().toString(), counter);
//每隔一秒重覆執行
handler.postDelayed(this, 1000);
}
};
private void sendToReceiver(String time,int number){
//預備將資料傳回給Receiver,由其來做UI的改變
Intent intent = new Intent(action);
Bundle bundle = new Bundle();
bundle.putString("time", time);
bundle.putInt("counter", number);
bundle.putString("action", "start");
intent.putExtras(bundle);
sendBroadcast(intent);
}
}
2013年6月20日 星期四
鐵馬族的好幫手 --> 樂活鐵馬 v1.10 已於 google play 上架
Google Maps 崁入式參數筆記
Google Maps嵌入參數
相關介紹
http://jax-work-archive.blogspot.tw/2011/07/google-maps.html
輸入範例
http://maps.google.com/maps?f=d&saddr=25.037525,121.56378199999995&daddr=25.063623,121.502297&hl=tw&dirflg=r
f=控制查詢表單的顯示風格。
f=d顯示成路徑規劃表單(有兩個輸入框,始點、終點)
Directions/路徑規劃
saddr= 出發點地址。
daddr=目標地址。
“+to:” 可以使用+to:子句增加多地點線路規劃時的目標地址信息,比如daddr=大石洞村+to:馬欄廣場+to:棠梨溝
mra ?? 此參數涵義未知,可能的取值:dm/dpe/cc/ls…
mrcr ??此參數涵義未知,可能的取值:0
mrsp解析座標到街名。
mrsp=0打開從座標解析街名
mrsp=1關閉從座標解析街名
mrad= 附加目標地址。如果你的行程有三個地點,你可以用saddr=,daddr=和mrad=表示,而不採用+to:子句。
dirflg 路線類型。
dirflg=h避免高速公路。
dirflg=t避免收費路段。
dirflg=r採用公共交通。僅在一些區域可用。還可以提出附加的時間信息。
dirflg=w步行方式。仍在測試狀態。
dirflg=b騎行方式。僅在某些區域可用,仍在測試狀態。
Output Control/輸出控制
hl=主機語言。僅支持一部分語言,如hl=fr表示法語
Google Geocoding API
原廠介紹
https://developers.google.com/maps/documentation/geocoding/?hl=zh-tw
輸入範例
https://maps.googleapis.com/maps/api/directions/json?origin=25.037525,121.56378199999995&destination=25.047924,121.51708099999996&sensor=false
https://maps.googleapis.com/maps/api/directions/json?origin=25.037525,121.56378199999995&destination=25.063623,121.502297&sensor=false&mode=walking
https://maps.googleapis.com/maps/api/directions/json?origin=25.037525,121.56378199999995&destination=25.063623,121.502297&sensor=false&mode=bicycling
https://maps.googleapis.com/maps/api/directions/json?origin=25.037525,121.56378199999995&destination=25.063623,121.502297&sensor=false&mode=driving
搜尋附近地區的方式
https://maps.google.com/?q=加油站&near=龍華科技大學
上述方法無法查到所要的結果
near 後方要接的參數應為 地方名稱,實際地址 or 實際地址
範例
https://maps.google.com/?q=加油站&near=龍華科技大學,333台灣桃園縣龜山鄉萬壽路一段300號
或使用 near=25.024173,121.401817
範例:
https://maps.google.com/?q=加油站&near=25.024173,121.401817
相關介紹
http://jax-work-archive.blogspot.tw/2011/07/google-maps.html
輸入範例
http://maps.google.com/maps?f=d&saddr=25.037525,121.56378199999995&daddr=25.063623,121.502297&hl=tw&dirflg=r
f=控制查詢表單的顯示風格。
f=d顯示成路徑規劃表單(有兩個輸入框,始點、終點)
Directions/路徑規劃
saddr= 出發點地址。
daddr=目標地址。
“+to:” 可以使用+to:子句增加多地點線路規劃時的目標地址信息,比如daddr=大石洞村+to:馬欄廣場+to:棠梨溝
mra ?? 此參數涵義未知,可能的取值:dm/dpe/cc/ls…
mrcr ??此參數涵義未知,可能的取值:0
mrsp解析座標到街名。
mrsp=0打開從座標解析街名
mrsp=1關閉從座標解析街名
mrad= 附加目標地址。如果你的行程有三個地點,你可以用saddr=,daddr=和mrad=表示,而不採用+to:子句。
dirflg 路線類型。
dirflg=h避免高速公路。
dirflg=t避免收費路段。
dirflg=r採用公共交通。僅在一些區域可用。還可以提出附加的時間信息。
dirflg=w步行方式。仍在測試狀態。
dirflg=b騎行方式。僅在某些區域可用,仍在測試狀態。
Output Control/輸出控制
hl=主機語言。僅支持一部分語言,如hl=fr表示法語
Google Geocoding API
原廠介紹
https://developers.google.com/maps/documentation/geocoding/?hl=zh-tw
輸入範例
https://maps.googleapis.com/maps/api/directions/json?origin=25.037525,121.56378199999995&destination=25.047924,121.51708099999996&sensor=false
https://maps.googleapis.com/maps/api/directions/json?origin=25.037525,121.56378199999995&destination=25.063623,121.502297&sensor=false&mode=walking
https://maps.googleapis.com/maps/api/directions/json?origin=25.037525,121.56378199999995&destination=25.063623,121.502297&sensor=false&mode=bicycling
https://maps.googleapis.com/maps/api/directions/json?origin=25.037525,121.56378199999995&destination=25.063623,121.502297&sensor=false&mode=driving
搜尋附近地區的方式
https://maps.google.com/?q=加油站&near=龍華科技大學
上述方法無法查到所要的結果
near 後方要接的參數應為 地方名稱,實際地址 or 實際地址
範例
https://maps.google.com/?q=加油站&near=龍華科技大學,333台灣桃園縣龜山鄉萬壽路一段300號
或使用 near=25.024173,121.401817
範例:
https://maps.google.com/?q=加油站&near=25.024173,121.401817
訂閱:
文章 (Atom)



