Android 手势控制解锁,滑动图片,照相,音乐切换,收音机换台,短信界面打电话


我的android版本是5.1的

我想要实现的是在设置里面有很多开关对应这些功能是否开放,并且有一个总开关来控制

默认都是关闭的效果。

我要说的是,我是通过距离传感器来实现这些功能的,

智能手机里面有很多种传感器,距离传感器是其中的一种,

要实现想要的功能,我是通过以下几步来实现的。


首先------>

在Setings主界面最下面加上一项手势控制

这一项我是在dashboard_categories.xml里加的,dashboard_categories是主界面的布局

里面的每一项都是一个dashboard,有对应的id,title,fragment,icon,如下

   <!-- Gesture induction -->     
         <dashboard-tile
                android:id="@+id/gesture_induction"
                android:title="@string/gesture_induction"
                android:fragment="com.android.settings.GestureInductionSettings"
                android:icon="@drawable/ic_settings_about"
                />

要想成功添加一项,这还远远不够,要在Strings.xml里面添加title的字符串

<string name="gesture_induction" product="default">Gesture Induction</string>

在Settings.java里面加上GestureInductionSettings继承SettingsActivity

在AndroidManifest.xml里配置这个activity,如下

 <activity android:name="Settings$GestureInductionSettingsActivity"
                android:theme="@style/Theme.SubSettingsDialogWhenLarge"
                android:label="@string/device_info_settings"
                android:taskAffinity="com.android.settings"
                android:parentActivityName="Settings">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.settings.GESTURE_INDUCTION_SETTINGS" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                android:value="com.android.settings.GestureInductionSettings" />
            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
                android:resource="@id/gesture_induction" />
        </activity>

在res的layout中添加gesture_induction_settings.xml布局文件,如下所示

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        android:title="@string/gesture_induction">
	
        	 
        <PreferenceCategory
        	 android:title="@string/support_gesture_apps">

                <SwitchPreference
                android:key="camera_gesture"
                android:title="@string/camera_gesture_title"
                android:summary="@string/camera_gesture_summary"
                android:persistent="false" />
                <SwitchPreference
                android:key="keyguard_gesture"
                android:title="@string/keyguard_gesture_title"
                android:summary="@string/keyguard_gesture_summary"
                android:persistent="false" />
                <SwitchPreference
                android:key="gallery2_gesture"
                android:title="@string/gallery2_gesture_title"
                android:summary="@string/gallery2_gesture_summary"
                android:persistent="false" />
                <SwitchPreference
                android:key="music_gesture"
                android:title="@string/music_gesture_title"
                android:summary="@string/music_gesture_summary"
                android:persistent="false" />
                <SwitchPreference
                android:key="fm_gesture"
                android:title="@string/fm_gesturee_title"
                android:summary="@string/fm_gesture_summary"
                android:persistent="false" />
	</PreferenceCategory>
                

</PreferenceScreen>
然后就是编写这个activity的代码了

package com.android.settings;

import android.os.Bundle;
import android.preference.Preference;
import android.app.Activity;
import android.preference.SwitchPreference;
import android.content.Context;
import android.content.ContentResolver;
import android.provider.Settings;
import android.content.res.Configuration;
import android.util.Log;
import com.android.settings.widget.SwitchBar;
import java.util.ArrayList;
import android.widget.Switch;

import static android.provider.Settings.System.CAMERA_GESTURE_MODE;
import static android.provider.Settings.System.KEYGUARD_GESTURE_MODE;
import static android.provider.Settings.System.GALLERY_GESTURE_MODE;
import static android.provider.Settings.System.MUSIC_GESTURE_MODE;
import static android.provider.Settings.System.FM_GESTURE_MODE;
import static android.provider.Settings.Global.GESTURE_SETTINGS_ENABLED;


public class GestureInductionSettings extends SettingsPreferenceFragment implements
        Preference.OnPreferenceChangeListener,SwitchBar.OnSwitchChangeListener{

    private static final String KEY_CAMERA_GESTURE = "camera_gesture";
    private static final String KEY_KEYGUARD_GESTURE = "keyguard_gesture";
    private static final String KEY_GALLERY_GESTURE = "gallery2_gesture";
    private static final String KEY_MUSIC_GESTURE = "music_gesture";
    private static final String KEY_FM_GESTURE = "fm_gesture";
  

    private SwitchPreference mCameraPreference;
    private SwitchPreference mKeyguardPreference;    
    private SwitchPreference mGalleryPreference;    
    private SwitchPreference mMusicPreference;    
    private SwitchPreference mFMPreference;
    private final Configuration mCurConfig = new Configuration();
    private SwitchBar mSwitchBar;
    private boolean mLastEnabledState;
     private final ArrayList<SwitchPreference> mAllPrefs = new ArrayList<SwitchPreference>();	

    
   	 public void onCreate(Bundle savedInstanceState) {
		
    	 super.onCreate(savedInstanceState);
		Log.i("SettingsQL GestureInductionSettings", "onCreate");
    	 final Activity activity = getActivity();
             		
   	 addPreferencesFromResource(R.xml.gesture_induction_settings);
	 mCameraPreference = (SwitchPreference) findPreference(KEY_CAMERA_GESTURE);
	 mKeyguardPreference = (SwitchPreference) findPreference(KEY_KEYGUARD_GESTURE);
	 mGalleryPreference = (SwitchPreference) findPreference(KEY_GALLERY_GESTURE);
	 mMusicPreference = (SwitchPreference) findPreference(KEY_MUSIC_GESTURE);
	 mFMPreference = (SwitchPreference) findPreference(KEY_FM_GESTURE);

	mAllPrefs.add(mCameraPreference);
	mAllPrefs.add(mKeyguardPreference);
	mAllPrefs.add(mGalleryPreference);
	mAllPrefs.add(mMusicPreference);
	mAllPrefs.add(mFMPreference);
	
	  mCameraPreference.setOnPreferenceChangeListener(this);
	  mKeyguardPreference.setOnPreferenceChangeListener(this);
	  mGalleryPreference.setOnPreferenceChangeListener(this);
	  mMusicPreference.setOnPreferenceChangeListener(this);
	  mFMPreference.setOnPreferenceChangeListener(this);
    	 }

	 @Override
   	 public void onResume() {
        	super.onResume();
		Log.i("SettingsQL GestureInductionSettings", "onResume");	
			updateState();
		 mLastEnabledState = Settings.Global.getInt(getActivity().getContentResolver(),
             		   Settings.Global.GESTURE_SETTINGS_ENABLED, 0) != 0;
		 Log.i("SettingsQL GestureInductionSettings", "onResume mLastEnabledState="+mLastEnabledState);
	 	mSwitchBar.setChecked(mLastEnabledState);
		mSwitchBar.show();
	 	setPrefsEnabledState(mLastEnabledState);
   	 }
	 private void setPrefsEnabledState(boolean enabled) {
        	for (int i = 0; i < mAllPrefs.size(); i++) {
           	 SwitchPreference pref = mAllPrefs.get(i);
           	 pref.setEnabled(enabled);
        	}
    	}
	 @Override
   	 public void onSwitchChanged(Switch switchView, boolean isChecked) {
        	if (switchView != mSwitchBar.getSwitch()) {
          	  return;
        	}
        	if (isChecked != mLastEnabledState) {
          	  if (isChecked) {  
			  	Log.i("SettingsQL GestureInductionSettings", "onSwitchChanged isChecked");
				Settings.Global.putInt(getActivity().getContentResolver(),
                    	       Settings.Global.GESTURE_SETTINGS_ENABLED, 1);
				setPrefsEnabledState(isChecked);
				mLastEnabledState = isChecked;
           	 } else {   
           	 		Log.i("SettingsQL GestureInductionSettings", "onSwitchChanged notChecked");
           	 		setGestureDisabled();
                		Settings.Global.putInt(getActivity().getContentResolver(),
                    	  	Settings.Global.GESTURE_SETTINGS_ENABLED, 0);
               		mLastEnabledState = isChecked;
                		setPrefsEnabledState(isChecked);
           	 }
        	}
    	}
	 private void setGestureDisabled(){
		mCameraPreference.setChecked(false);
		 Settings.System.putInt(getContentResolver(), CAMERA_GESTURE_MODE,0);
		 mKeyguardPreference.setChecked(false);
		 Settings.System.putInt(getContentResolver(), KEYGUARD_GESTURE_MODE,0);
		 mGalleryPreference.setChecked(false);
		 Settings.System.putInt(getContentResolver(), GALLERY_GESTURE_MODE,0);
		 mMusicPreference.setChecked(false);
		 Settings.System.putInt(getContentResolver(), MUSIC_GESTURE_MODE,0);
		 mFMPreference.setChecked(false);
		 Settings.System.putInt(getContentResolver(), FM_GESTURE_MODE,0);
	 };
	  @Override
    	public void onConfigurationChanged(Configuration newConfig) {

        	super.onConfigurationChanged(newConfig);
        	mCurConfig.updateFrom(newConfig);
    	}

	@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        final SettingsActivity activity = (SettingsActivity) getActivity();

        mSwitchBar = activity.getSwitchBar();
		 mSwitchBar.setEnabled(true);

        mSwitchBar.addOnSwitchChangeListener(this);
    }
	 private void updateState() {
		Log.i("SettingsQL GestureInductionSettings", "updateState");
       	 if (mCameraPreference != null) {
          	  int cameraGestureMode = Settings.System.getInt(getContentResolver(),
                    CAMERA_GESTURE_MODE, 0);
         	   mCameraPreference.setChecked(cameraGestureMode != 0);
       	 }
		 if (mKeyguardPreference != null) {
          	  int keyguardGestureMode = Settings.System.getInt(getContentResolver(),
                    KEYGUARD_GESTURE_MODE, 0);
         	   mKeyguardPreference.setChecked(keyguardGestureMode != 0);
       	 }
		 if (mGalleryPreference != null) {
          	  int galleryGestureMode = Settings.System.getInt(getContentResolver(),
                    GALLERY_GESTURE_MODE, 0);
         	   mGalleryPreference.setChecked(galleryGestureMode != 0);
       	 }
		 if (mMusicPreference != null) {
          	  int musicGestureMode = Settings.System.getInt(getContentResolver(),
                    MUSIC_GESTURE_MODE, 0);
	 	  Log.i("SettingsQL GestureInductionSettings", "updateState musicGestureMode="+musicGestureMode);
         	   mMusicPreference.setChecked(musicGestureMode != 0);
       	 }
		 if (mFMPreference != null) {
          	  int fmGestureMode = Settings.System.getInt(getContentResolver(),
                    FM_GESTURE_MODE, 0);
         	   mFMPreference.setChecked(fmGestureMode != 0);
       	 }

        	
      	  }
	
    	@Override
    	public void onPause() {
        	super.onPause();
		Log.i("SettingsQL GestureInductionSettings", "onPause");
    	}

    	@Override
	public boolean onPreferenceChange(Preference preference, Object objValue) {
	Log.i("SettingsQL GestureInductionSettings", "onPreferenceChange");
		  if (preference == mCameraPreference) {
            boolean enable = (Boolean) objValue;
            Settings.System.putInt(getContentResolver(), CAMERA_GESTURE_MODE,
                    enable ? 1 : 0);
        	}
		    if (preference == mKeyguardPreference) {
            boolean enable = (Boolean) objValue;
            Settings.System.putInt(getContentResolver(), KEYGUARD_GESTURE_MODE,
                    enable ? 1 : 0);
        	}
			  if (preference == mGalleryPreference) {
            boolean enable = (Boolean) objValue;
            Settings.System.putInt(getContentResolver(), GALLERY_GESTURE_MODE,
                    enable ? 1 : 0);
        	}
			    if (preference == mMusicPreference) {
            boolean enable = (Boolean) objValue;
            Settings.System.putInt(getContentResolver(), MUSIC_GESTURE_MODE,
                    enable ? 1 : 0);
        	}
				  if (preference == mFMPreference) {
            boolean enable = (Boolean) objValue;
            Settings.System.putInt(getContentResolver(), FM_GESTURE_MODE,
                    enable ? 1 : 0);
        	}
		return true;		  
	}

	
}
等下再来解释代码的含义。

至此,设置里面的编辑就算完成了。


然后------>

现在我要编写的是frameworks层的东西。

由于设置里面要将开关的值保存到数据库,所以肯定要用到

android.provider.Settings这个类以及SettingsProvider这个应用

在电量百分比这篇文章里我已经写了一些关于这两个东西的作用

点击打开链接

首先要在defaults.xml里面加入默认值。

    <bool name="def_camera_gesture_mode">false</bool>
    <bool name="def_keyguard_gesture_mode">false</bool>
    <bool name="def_gallery_gesture_mode">false</bool>
    <bool name="def_music_gesture_mode">false</bool>
    <bool name="def_fm_gesture_mode">false</bool>
    <bool name="def_gesture_settings_enabled">false</bool>

然后在android.provider.Settings.System中加入各个功能静态值
	  public static String CAMERA_GESTURE_MODE="camera_gesture_mode";
	  public static String KEYGUARD_GESTURE_MODE="keyguard_gesture_mode";
	  public static String GALLERY_GESTURE_MODE="gallery_gesture_mode";
	  public static String MUSIC_GESTURE_MODE="music_gesture_mode";
	  public static String FM_GESTURE_MODE="fm_gesture_mode";
然后在android.provider.Settings.Global中加入总开关的静态值

public static  String GESTURE_SETTINGS_ENABLED="gesture_settings_enabled";

然后在DatabaseHelper中的loadSystemSettings中加入

loadBooleanSetting(stmt, Settings.System.CAMERA_GESTURE_MODE,
                    R.bool.def_camera_gesture_mode);
	    loadBooleanSetting(stmt, Settings.System.KEYGUARD_GESTURE_MODE,
                    R.bool.def_keyguard_gesture_mode);
	    loadBooleanSetting(stmt, Settings.System.GALLERY_GESTURE_MODE,
                    R.bool.def_gallery_gesture_mode);
           loadBooleanSetting(stmt, Settings.System.MUSIC_GESTURE_MODE,
                    R.bool.def_music_gesture_mode);
	    loadBooleanSetting(stmt, Settings.System.FM_GESTURE_MODE,
                    R.bool.def_fm_gesture_mode);
用来将各个开关的默认值写入数据库System中

然后在DatabaseHelper中的loadGlobalSettings中加入

loadBooleanSetting(stmt, Settings.Global.GESTURE_SETTINGS_ENABLED,
                    R.bool.def_gesture_settings_enabled);
用来将总开关的默认值写入数据库Global中


最后------>

就是各个应用的编写了,我需要在各个应用中将数据库中的值取到,

然后用这个值来决定是否打开距离传感器来控制想要的功能

1》照相功能的实现:

找到CameraActivity,我把要加入的代码贴出来

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;
import android.provider.Settings;
import static android.provider.Settings.System.CAMERA_GESTURE_MODE;

//成员变量
	private SensorManager sensorManager=null;
	private Sensor proximitySensor=null;
	private boolean mNeedSensorToWork=false;
	private ProximitySensorEventListener mProximitySensorListener=null;
	private int gestureValue;

//onCreate方法中添加
sensorManager =
			(SensorManager)getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
	proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
	if (proximitySensor == null) {
		mProximitySensorListener = null;
	} else {
		mProximitySensorListener =
				new ProximitySensorEventListener(sensorManager, proximitySensor);
	}

//onResume方法中添加
gestureValue=Settings.System.getInt(getContentResolver(), CAMERA_GESTURE_MODE,0);
	mNeedSensorToWork=gestureValue==1?true:false;
	if(mNeedSensorToWork){

	mProximitySensorListener.register();
	}
//onPause方法中添加
mProximitySensorListener.unregister();

//监听和执行
public static enum State {
	NEAR, FAR
}
private  class ProximitySensorEventListener implements SensorEventListener{
	private final SensorManager mSensorManager;
	private final Sensor mProximitySensor;
	private final float mMaxValue;


	private State mLastState=State.FAR;


	public ProximitySensorEventListener(SensorManager sensorManager, Sensor proximitySensor
			) {
		mSensorManager = sensorManager;
		mProximitySensor=proximitySensor;
		mMaxValue=proximitySensor.getMaximumRange();

	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		float value=event.values[0];
		State state=getStateFromValue(value);
		if(state==State.NEAR&&mLastState==State.FAR){
			mLastState=State.NEAR;
			return;
		}
		if(state==State.FAR&&mLastState==State.NEAR){
			Log.i("Gallery2QL", "onSensorChanged");
			mCameraAppUi.getPhotoShutter().performClick();
			mLastState=State.FAR;
		}

	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}
	/** Returns the state of the sensor given its current value. */
	private State getStateFromValue(float value) {
		return value==mMaxValue ? State.FAR : State.NEAR;
	}

	public synchronized void register() {
		// It is okay to register multiple times.
		mSensorManager.registerListener(this, mProximitySensor, SensorManager.SENSOR_DELAY_UI);
	}

	public synchronized void unregister() {			
		mSensorManager.unregisterListener(this);
		// Always go back to the FAR state. That way, when we register again we will get a
		// transition when the sensor gets into the NEAR state.
		mLastState = State.FAR;		
	}

}





照相主要就是执行了
mCameraAppUi.getPhotoShutter().performClick();这个方法

2》解锁功能实现

找到KeyguardSimpleHostView

解锁用到的方法其实是KeyguardViewBase里面的dismiss()方法

3》相册翻页功能实现

找到photoView,翻页调用的是 slideToNextPicture()方法

4》音乐播放下一曲

找到MediaPlaybackActivity

直接在onSensorChange相应的位置调用

 mPerformanceTestString = NEXT_TEST;
Message msg = mHandler.obtainMessage(NEXT_BUTTON, null);
mHandler.removeMessages(NEXT_BUTTON);
mHandler.sendMessage(msg);

即可

5》收音机换台

找到FmMainActivity

换台调用的是seekStation(mCurrentStation, true);

以上几个应用我都只说具体功能操作的主要方法,没有向照相那样说的详细,

其实大同小异,只是代码加的地方有些不同罢了。


至此,基本已经说完了。

主要还有GestureInductionSettings这个类,它的功能实现可以参考Settings里面的一些

SubSettings来实现。


后续有时间再来补充。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值