“翻转静音”的Android实现 android 翻转静音

“翻转静音”的Android实现

有朋友很想要Symbian系统上来电话时翻转静音的功能,于是帮其实现之。

因其手机为Android1.5版本,所以使用了部分老旧的API,参考时请注意。

  

要求功能:

设置是否开启翻转静音功能——上图“电话”选项。

设置功能开始状态下在托盘区是否显示图标——上图“托盘图标”选项。

设置触发静音的翻转角度——上图“翻转触发角度”选项,另点击“当前手机角度”可直接将触发角度设为当前手机倾斜角度。

详细见下图:



程序设计:

主体结构

提供用户设置的界面——TurnSilenceActivity

在后台运行,来电话时监视翻转进行静音的服务——TurnSilenceService

接受系统消息,在开机时启动翻转静音服务——TurnSilenceReceiver

主要技术

获知来电话事件——PhoneStateListener

获取手机倾斜角度——TYPE_ACCELEROMETER

改变手机振铃模式——AUDIO_SERVICE

显示托盘图标——NOTIFICATION_SERVICE

保存用户设定——SharedPreferences

详细见下图:



代码实现:

TurnSilenceReceiver.java

public class TurnSilenceReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

TurnSilenceResource mTsRes = new TurnSilenceResource(context);

boolean optCallFlg = mTsRes.getOptCallValue();

if (true == optCallFlg) {

TurnSilenceUtility.startService(mTsRes, TurnSilenceService.class,

TurnSilenceActivity.class);

}

}

}TurnSilenceActivity.java

public class TurnSilenceActivity extends PreferenceActivity implements

OnPreferenceChangeListener, OnPreferenceClickListener {

private SensorManager mSensorMgr;

private Sensor mGravitySensor;

private double mDegreeDbl;

private TurnSilenceResource mTsRes;

private EditTextPreference mOptTriggerDegreeEditTextPref;

private Preference mOptRealDegreePref;

private final SensorEventListener mSensorEventListener = new SensorEventListener() {

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

@Override

public void onSensorChanged(SensorEvent event) {

double g = TurnSilenceUtility.GRAVITY;

double degreeDbl;

String degreeStr;

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

degreeDbl = event.values[SensorManager.DATA_Z];

if (g < Math.abs(degreeDbl)) {

g = Math.abs(degreeDbl);

}

degreeDbl = Math.asin(degreeDbl / g);

mDegreeDbl = degreeDbl * TurnSilenceUtility.DEGREE_PI / Math.PI;

degreeStr = String.format(mTsRes.getOptRealDegreeFormat(),

mDegreeDbl);

mOptRealDegreePref.setSummary(degreeStr);

}

}

};

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

addPreferencesFromResource(R.layout.options);

mTsRes = new TurnSilenceResource(this);

getPreferenceScreen().findPreference(mTsRes.getOptCallKey())

.setOnPreferenceChangeListener(this);

mOptRealDegreePref = getPreferenceScreen().findPreference(

mTsRes.getOptRealDegreeKey());

mOptRealDegreePref.setOnPreferenceClickListener(this);

mOptTriggerDegreeEditTextPref = (EditTextPreference) getPreferenceScreen()

.findPreference(mTsRes.getOptTriggerDegreeKey());

“翻转静音”的Android实现 android 翻转静音
mOptTriggerDegreeEditTextPref.setOnPreferenceChangeListener(this);

if (true == mTsRes.getOptCallValue()) {

TurnSilenceUtility.startService(mTsRes, TurnSilenceService.class,

TurnSilenceActivity.class);

}

mSensorMgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

mGravitySensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

}

@Override

protected void onResume() {

super.onResume();

mSensorMgr.registerListener(mSensorEventListener, mGravitySensor,

SensorManager.SENSOR_DELAY_NORMAL);

}

@Override

protected void onPause() {

mSensorMgr.unregisterListener(mSensorEventListener);

super.onPause();

}

@Override

public boolean onPreferenceChange(Preference preference, Object newValue) {

String key;

boolean ret = false;

key = preference.getKey();

if (mTsRes.getOptCallKey().equals(key)) {

if (true == mTsRes.getOptCallValue()) {

TurnSilenceUtility

.stopService(mTsRes, TurnSilenceService.class);

} else {

TurnSilenceUtility.startService(mTsRes,

TurnSilenceService.class, TurnSilenceActivity.class);

}

ret = true;

} else if (mTsRes.getOptTriggerDegreeKey().equals(key)) {

try {

Double.parseDouble((String) newValue);

ret = true;

} catch (NumberFormatException e) {

ret = false;

}

}

return ret;

}

@Override

public boolean onPreferenceClick(Preference preference) {

String key = preference.getKey();

if (mTsRes.getOptRealDegreeKey().equals(key)) {

String degreeStr;

degreeStr = Double.toString(mDegreeDbl);

mOptTriggerDegreeEditTextPref.setText(degreeStr);

}

return true;

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

super.onCreateOptionsMenu(menu);

MenuInflater inflater = getMenuInflater();

inflater.inflate(R.menu.menu, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.item_about:

startActivity(new Intent(this, TurnSilenceAbout.class));

return true;

case R.id.item_exit:

mSensorMgr.unregisterListener(mSensorEventListener);

finish();

return true;

}

return false;

}

}TurnSilenceService.java

public class TurnSilenceService extends Service implements

OnSharedPreferenceChangeListener {

private NotificationManager mNotificationMgr;

private TelephonyManager mTelephonyMgr;

private AudioManager mAudioMgr;

private SensorManager mSensorMgr;

private Sensor mGravitySensor;

private boolean mGravitySensorFlg = false;

private boolean mUpwardFlg = false;

private int mRingerMode;

private double mTriggerDegree;

private TurnSilenceResource mTsRes;

private Class<?> mMainClass;

private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {

@Override

public void onCallStateChanged(final int state,

final String incomingNumber) {

switch (state) {

case TelephonyManager.CALL_STATE_RINGING:

if (false == mGravitySensorFlg) {

mRingerMode = mAudioMgr.getRingerMode();

if (AudioManager.RINGER_MODE_SILENT != mRingerMode) {

mSensorMgr.registerListener(mSensorEventListener,

mGravitySensor,

SensorManager.SENSOR_DELAY_NORMAL);

mGravitySensorFlg = true;

}

}

break;

case TelephonyManager.CALL_STATE_OFFHOOK:

case TelephonyManager.CALL_STATE_IDLE:

if (true == mGravitySensorFlg) {

mSensorMgr.unregisterListener(mSensorEventListener);

mAudioMgr.setRingerMode(mRingerMode);

mGravitySensorFlg = false;

}

break;

default:

break;

}

}

};

private final SensorEventListener mSensorEventListener = new SensorEventListener() {

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

@Override

public void onSensorChanged(SensorEvent event) {

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

if (event.values[SensorManager.DATA_Z] >= mTriggerDegree) {

mUpwardFlg = true;

} else {

if (true == mUpwardFlg) {

mAudioMgr

.setRingerMode(AudioManager.RINGER_MODE_SILENT);

mUpwardFlg = false;

}

}

}

}

};

@Override

public IBinder onBind(Intent intent) {

return null;

}

@Override

public void onCreate() {

super.onCreate();

mTsRes = new TurnSilenceResource(this);

mTsRes.regOnSharedPrefChangeListener(this);

mTriggerDegree = getTriggerDegree();

mTelephonyMgr = (TelephonyManager) this

.getSystemService(Context.TELEPHONY_SERVICE);

mTelephonyMgr.listen(mPhoneStateListener,

PhoneStateListener.LISTEN_CALL_STATE);

mAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

mSensorMgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

mGravitySensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

mNotificationMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

}

@Override

public void onStart(Intent intent, int startId) {

String str;

str = intent.getExtras().getString(mTsRes.getDataMainClassKey());

try {

mMainClass = Class.forName(str);

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

if (true == mTsRes.getOptTrayValue()) {

showTrayIcon();

}

}

@Override

public void onDestroy() {

if (true == mGravitySensorFlg) {

mSensorMgr.unregisterListener(mSensorEventListener);

mAudioMgr.setRingerMode(mRingerMode);

mGravitySensorFlg = false;

}

mTelephonyMgr.listen(mPhoneStateListener,

PhoneStateListener.LISTEN_NONE);

mTsRes.unregOnSharedPrefChangeListener(this);

if (true == mTsRes.getOptTrayValue()) {

hideTrayIcon();

}

super.onDestroy();

}

@Override

public void onSharedPreferenceChanged(SharedPreferences sharedPref,

String key) {

if (mTsRes.getOptTriggerDegreeKey().equals(key)) {

mTriggerDegree = getTriggerDegree();

if (true == mTsRes.getOptTrayValue()) {

showTrayIcon();

}

} else if (mTsRes.getOptTrayKey().equals(key)) {

if (true == mTsRes.getOptTrayValue()) {

showTrayIcon();

} else {

hideTrayIcon();

}

}

}

private double getTriggerDegree() {

double degreeDbl;

String degreeStr = mTsRes.getOptTriggerDegreeValue();

degreeDbl = Double.parseDouble(degreeStr);

degreeDbl = degreeDbl * Math.PI / TurnSilenceUtility.DEGREE_PI;

degreeDbl = Math.sin(degreeDbl);

degreeDbl = degreeDbl * TurnSilenceUtility.GRAVITY;

return degreeDbl;

}

private void showTrayIcon() {

int trayIconID = 0;

String tickerText = null;

long when = 0L;

Notification notification;

String trayNotificationTitle;

String trayNotificationFormat;

String trayNotificationText;

Intent trayNotificationIntent;

PendingIntent trayNotificationPendingIntent;

double degreeDbl = 0;

String degreeStr = null;

trayNotificationTitle = mTsRes.getOptTrayNotificationTitle();

trayNotificationFormat = mTsRes.getOptTrayNotificationFormat();

degreeStr = mTsRes.getOptTriggerDegreeValue();

degreeDbl = Double.parseDouble(degreeStr);

trayNotificationText = String.format(trayNotificationFormat, degreeDbl);

trayNotificationIntent = new Intent(this, mMainClass);

trayNotificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP

| Intent.FLAG_ACTIVITY_NEW_TASK);

trayNotificationPendingIntent = PendingIntent.getActivity(this,

TurnSilenceUtility.NOTIFICATION_ID_TRAY,

trayNotificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

trayIconID = mTsRes.getTrayIconId();

tickerText = mTsRes.getOptTrayTickerText();

when = System.currentTimeMillis();

notification = new Notification(trayIconID, tickerText, when);

notification.flags = Notification.FLAG_ONGOING_EVENT;

notification.setLatestEventInfo(this, trayNotificationTitle,

trayNotificationText, trayNotificationPendingIntent);

mNotificationMgr.notify(TurnSilenceUtility.NOTIFICATION_ID_TRAY,

notification);

return;

}

private void hideTrayIcon() {

mNotificationMgr.cancel(TurnSilenceUtility.NOTIFICATION_ID_TRAY);

return;

}

}TurnSilenceAbout.java

public class TurnSilenceAbout extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.about);

}

}TurnSilenceUtility.java

public class TurnSilenceUtility {

public static final double GRAVITY = 9.81;

public static final double DEGREE_PI = 180;

public static final int NOTIFICATION_ID_TRAY = 0;

public static void startService(TurnSilenceResource tsRes, Class<?> destCls,

Class<?> mainCls) {

Context context;

String str = null;

Intent i;

context = tsRes.getAppContext();

i = new Intent(context, destCls);

str = mainCls.getCanonicalName();

i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

i.putExtra(tsRes.getDataMainClassKey(), str);

context.startService(i);

}

public static void stopService(TurnSilenceResource tsRes, Class<?> destCls) {

Context context;

Intent i;

context = tsRes.getAppContext();

i = new Intent(context, destCls);

context.stopService(i);

}

}TurnSilenceResource.java

public class TurnSilenceResource {

private Context mAppContext;

private SharedPreferences mSharedPref;

private String mOptCallKey = null;

private boolean mOptCallDefaultValue = false;

private String mOptRealDegreeKey = null;

private String mOptRealDegreeFormat = null;

private String mOptTriggerDegreeKey = null;

private String mOptTriggerDegreeDefaultValue = null;

private String mOptTrayKey = null;

private boolean mOptTrayDefaultValue = false;

private String mOptTrayTickerText = null;

private String mOptTrayNotificationTitle = null;

private String mOptTrayNotificationFormat = null;

private String mDataMainClassKey = null;

private int mTrayIcon = 0;

public TurnSilenceResource(Context context) {

getStringValue(context);

getResId();

mSharedPref = PreferenceManager.getDefaultSharedPreferences(context);

mAppContext = context;

}

public String getOptCallKey() {

return mOptCallKey;

}

public String getOptRealDegreeKey() {

return mOptRealDegreeKey;

}

public String getOptRealDegreeFormat() {

return mOptRealDegreeFormat;

}

public String getOptTriggerDegreeKey() {

return mOptTriggerDegreeKey;

}

public String getOptTrayKey() {

return mOptTrayKey;

}

public String getOptTrayTickerText() {

return mOptTrayTickerText;

}

public String getOptTrayNotificationTitle() {

return mOptTrayNotificationTitle;

}

public String getOptTrayNotificationFormat() {

return mOptTrayNotificationFormat;

}

public String getDataMainClassKey() {

return mDataMainClassKey;

}

public Context getAppContext() {

return mAppContext;

}

public int getTrayIconId() {

return mTrayIcon;

}

public boolean getOptCallValue() {

return mSharedPref.getBoolean(mOptCallKey, mOptCallDefaultValue);

}

public String getOptTriggerDegreeValue() {

return mSharedPref.getString(mOptTriggerDegreeKey,

mOptTriggerDegreeDefaultValue);

}

public boolean getOptTrayValue() {

return mSharedPref.getBoolean(mOptTrayKey, mOptTrayDefaultValue);

}

public void regOnSharedPrefChangeListener(

OnSharedPreferenceChangeListener listener) {

mSharedPref.registerOnSharedPreferenceChangeListener(listener);

}

public void unregOnSharedPrefChangeListener(

OnSharedPreferenceChangeListener listener) {

mSharedPref.unregisterOnSharedPreferenceChangeListener(listener);

}

private void getStringValue(Context context) {

String str = null;

mOptCallKey = context.getResources().getString(R.string.opt_call_key);

str = context.getResources().getString(R.string.opt_call_default_value);

mOptCallDefaultValue = Boolean.valueOf(str);

mOptRealDegreeKey = context.getResources().getString(

R.string.opt_real_degree_key);

mOptTriggerDegreeKey = context.getResources().getString(

R.string.opt_trigger_degree_key);

mOptTriggerDegreeDefaultValue = context.getResources().getString(

R.string.opt_trigger_degree_default_value);

mOptRealDegreeFormat = context.getResources().getString(

R.string.opt_real_degree_format);

mOptTrayKey = context.getResources().getString(R.string.opt_tray_key);

mOptTrayDefaultValue = false;

str = context.getResources().getString(R.string.opt_tray_default_value);

mOptTrayDefaultValue = Boolean.valueOf(str);

mOptTrayTickerText = context.getResources().getString(

R.string.opt_tray_ticker_text);

mOptTrayNotificationTitle = context.getResources().getString(

R.string.opt_tray_notification_title);

mOptTrayNotificationFormat = context.getResources().getString(

R.string.opt_tray_notification_title);

mOptTrayNotificationFormat = context.getResources().getString(

R.string.opt_tray_notification_format);

mDataMainClassKey = context.getResources().getString(

R.string.data_main_class_key);

}

private void getResId() {

mTrayIcon = R.drawable.icon;

}

}res/layout/option.xml

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<CheckBoxPreference android:key="@string/opt_call_key"

android:title="@string/opt_call_title" android:summary="@string/opt_call_summary"

android:defaultValue="@string/opt_call_default_value" />

<Preference android:key="@string/opt_real_degree_key"

android:title="@string/opt_real_degree_title" android:summary="@string/opt_real_degree_summary" />

<EditTextPreference android:key="@string/opt_trigger_degree_key"

android:title="@string/opt_trigger_degree_title" android:summary="@string/opt_trigger_degree_summary"

android:dialogTitle="@string/opt_trigger_degree_dialogtitle"

android:defaultValue="@string/opt_trigger_degree_default_value"

android:inputType="numberSigned|numberDecimal" />

<CheckBoxPreference android:key="@string/opt_tray_key"

android:title="@string/opt_tray_title" android:summary="@string/opt_tray_summary"

android:defaultValue="@string/opt_tray_default_value" />

</PreferenceScreen> res/layout/about.xml

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent" android:layout_height="fill_parent"

android:padding="10dip">

<TextView android:id="@+id/about_content"

android:layout_width="wrap_content" android:layout_height="wrap_content"

android:text="@string/about_text" />

</ScrollView> res/menu/menu.xml

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/item_about" android:title="@string/item_about_label"

android:alphabeticShortcut="@string/item_about_shortcut" />

<item android:id="@+id/item_exit" android:title="@string/item_exit_label"

android:alphabeticShortcut="@string/item_exit_shortcut" />

</menu> res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>

<resources>

<string name="hello">Hello World, TurnSilence!</string>

<string name="app_name">翻转静音</string>

<string name="opt_call_key">opt_call</string>

<string name="opt_call_title">电话</string>

<string name="opt_call_summary">来电时进行翻转静音</string>

<string name="opt_call_default_value">true</string>

<string name="opt_real_degree_key">opt_real_degree</string>

<string name="opt_real_degree_title">当前手机角度</string>

<string name="opt_real_degree_summary">设置翻转触发角度</string>

<string name="opt_real_degree_format">点击设置翻转触发角度为:%1$.0f°</string>

<string name="opt_trigger_degree_key">opt_trigger_degree</string>

<string name="opt_trigger_degree_title">翻转触发角度</string>

<string name="opt_trigger_degree_dialogtitle">输入角度</string>

<string name="opt_trigger_degree_summary">指定翻转触发角度</string>

<string name="opt_trigger_degree_default_value">-60</string>

<string name="opt_tray_key">opt_tray_key</string>

<string name="opt_tray_title">托盘图标</string>

<string name="opt_tray_summary">服务时显示托盘图标</string>

<string name="opt_tray_default_value">true</string>

<string name="item_about_label">关于</string>

<string name="item_about_shortcut">a</string>

<string name="item_exit_label">退出</string>

<string name="item_exit_shortcut">x</string>

<string name="about_title">About</string>

<string name="about_text">



送给我的朋友;)

</string>

<string name="opt_tray_ticker_text">翻转静音启动!</string>

<string name="opt_tray_notification_title">翻转静音</string>

<string name="opt_tray_notification_format">触发角度为:%1$.0f°</string>

<string name="data_main_class_key">data_main_class_key</string>

</resources> AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="org.mtyy110.android.turnsilence" android:versionCode="1"

android:versionName="1.0">

<application android:icon="@drawable/icon" android:label="@string/app_name">

<receiver android:name=".TurnSilenceReceiver">

<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED" />

<category android:name="android.intent.category.HOME" />

</intent-filter>

</receiver>

<service android:name=".TurnSilenceService">

</service>

<activity android:name=".TurnSilenceActivity" android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

<activity android:name=".TurnSilenceAbout" android:label="@string/about_title"

android:theme="@android:style/Theme.Dialog">

</activity>

</application>

<uses-sdk android:minSdkVersion="3" />

</manifest>

  

爱华网本文地址 » http://www.aihuau.com/a/25101012/136409.html

更多阅读

细致完整的Android开发环境搭建教程 android源码环境搭建

??????? 相信学习Android开发的程序猿们都晓得,?首先就是android开发环境搭建。这一课说起来简单,但是对不少Android开发入门的小白来说还是一个难点,在安卓环境搭建过程中会遇到各种各样的问题,今天就来为大家汇总归纳关于android

完整的Android开发环境Eclipse+ADT+SDK(22.0.1) eclipse adt sdk 一套

现在开始学习Android嵌入式编程,首要的问题就是在Windows中搭建开发环境,就这个都要摸索很长的时间,总是在版本之间折腾折腾去,而且Google的Android正式差劲得很,经常是连不上,要不就是服务器改变了路径。把我收集的完整的搭建好的分享给

基于FPGA IP核的FFT实现 altera fft ip核

基于FPGA IP核的FFT实现(1/1)0 引 言数字信号处理数字信号处理数字信号处理就是用数值计算方法对数字序列进行各种处理,把信号变换成符合需要的某种形式。理论基础,其中最主要的是离散时间信号和离散时间系统理论以及一些数学理论。领

声明:《“翻转静音”的Android实现 android 翻转静音》为网友一切一切分享!如侵犯到您的合法权益请联系我们删除