تشخیص لرزش گوشی در اندروید

سلام دوستان امروز میخواهیم به تشخیص لرزش گوشی در اندروید یا shake در اندروید بپردازیم.منظور از shake و لرزش در اندروید هنگامی است که گوشی خود را تکان می دهید شاید بار ها در برنامه های مختلف دیده باشید که با تکان دادن گوشی عملیاتی انجام داده میشود.برای اینکار روش های مختلفی را داریم و ما در اینجا به روشی میپردازیم که نسبتا جدید و دقیق تر است.دوستان بررسی تمام بخش های این دستورات از حوصله این اموزش خارج است و میتوانید قسمت های مختلف ان را در سایت در صورت وجود پیدا کنید.
قبل از شروع ابتدا اجازه دسترسی به برناممان می دهیم :

<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

ما برای اینکار از AccelerometerListener استفاده میکنیم که باید ان را در قالب interface ایجاد کنیم و اکتیویتی اصلیمان را از این رابط implements میکنیم که در بخش کد های MainActivity خواهید دید.
خب قبل از رفتن  به اکتیویتی اصلی لازمه که ابتدا این interface را ایجاد کنید برای اینکار هنگام ایجاد یک فایل جاوا interface را انتخاب کنید سپس کد های زیر را در ان بنویسید در اینجا ما نام فایل را AccelerometerListener قرار داده ایم :

public interface AccelerometerListener {
    public void onAccelerationChanged(float x, float y, float z);
    public void onShake(float force);
}

حالا یک کلاس ایجاد کنید و کد های زیر را در ان قرار دهید نام این کلاس در اینجا AccelerometerManager می باشد:

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.Toast;
import java.util.List;
/**
 * Created by Sepehr on 18/07/2017.
 */
public class AccelerometerManager {
    private static Context aContext=null;
    /** Accuracy configuration */
    private static float threshold  = 15.0f;
    private static int interval     = 200;
    private static Sensor sensor;
    private static SensorManager sensorManager;
    // you could use an OrientationListener array instead
    // if you plans to use more than one listener
    private static AccelerometerListener listener;
    /** indicates whether or not Accelerometer Sensor is supported */
    private static Boolean supported;
    /** indicates whether or not Accelerometer Sensor is running */
    private static boolean running = false;
    /**
     * Returns true if the manager is listening to orientation changes
     */
    public static boolean isListening() {
        return running;
    }
    /**
     * Unregisters listeners
     */
    public static void stopListening() {
        running = false;
        try {
            if (sensorManager != null && sensorEventListener != null) {
                sensorManager.unregisterListener(sensorEventListener);
            }
        } catch (Exception e) {}
    }
    /**
     * Returns true if at least one Accelerometer sensor is available
     */
    public static boolean isSupported(Context context) {
        aContext = context;
        if (supported == null) {
            if (aContext != null) {
                sensorManager = (SensorManager) aContext.
                        getSystemService(Context.SENSOR_SERVICE);
                // Get all sensors in device
                List<Sensor> sensors = sensorManager.getSensorList(
                        Sensor.TYPE_ACCELEROMETER);
                supported = new Boolean(sensors.size() > 0);
            } else {
                supported = Boolean.FALSE;
            }
        }
        return supported;
    }
    /**
     * Configure the listener for shaking
     * @param threshold
     *             minimum acceleration variation for considering shaking
     * @param interval
     *             minimum interval between to shake events
     */
    public static void configure(int threshold, int interval) {
        AccelerometerManager.threshold = threshold;
        AccelerometerManager.interval = interval;
    }
    /**
     * Registers a listener and start listening
     * @param accelerometerListener
     *             callback for accelerometer events
     */
    public static void startListening( AccelerometerListener accelerometerListener )
    {
        sensorManager = (SensorManager) aContext.
                getSystemService(Context.SENSOR_SERVICE);
        // Take all sensors in device
        List<Sensor> sensors = sensorManager.getSensorList(
                Sensor.TYPE_ACCELEROMETER);
        if (sensors.size() > 0) {
            sensor = sensors.get(0);
            // Register Accelerometer Listener
            running = sensorManager.registerListener(
                    sensorEventListener, sensor,
                    SensorManager.SENSOR_DELAY_GAME);
            listener = accelerometerListener;
        }
    }
    /**
     * Configures threshold and interval
     * And registers a listener and start listening
     * @param accelerometerListener
     *             callback for accelerometer events
     * @param threshold
     *             minimum acceleration variation for considering shaking
     * @param interval
     *             minimum interval between to shake events
     */
    public static void startListening(
            AccelerometerListener accelerometerListener,
            int threshold, int interval) {
        configure(threshold, interval);
        startListening(accelerometerListener);
    }
    /**
     * The listener that listen to events from the accelerometer listener
     */
    private static SensorEventListener sensorEventListener =
            new SensorEventListener() {
                private long now = 0;
                private long timeDiff = 0;
                private long lastUpdate = 0;
                private long lastShake = 0;
                private float x = 0;
                private float y = 0;
                private float z = 0;
                private float lastX = 0;
                private float lastY = 0;
                private float lastZ = 0;
                private float force = 0;
                public void onAccuracyChanged(Sensor sensor, int accuracy) {}
                public void onSensorChanged(SensorEvent event) {
                    // use the event timestamp as reference
                    // so the manager precision won't depends
                    // on the AccelerometerListener implementation
                    // processing time
                    now = event.timestamp;
                    x = event.values[0];
                    y = event.values[1];
                    z = event.values[2];
                    // if not interesting in shake events
                    // just remove the whole if then else block
                    if (lastUpdate == 0) {
                        lastUpdate = now;
                        lastShake = now;
                        lastX = x;
                        lastY = y;
                        lastZ = z;
                        Toast.makeText(aContext,"No Motion detected",
                                Toast.LENGTH_SHORT).show();
                    } else {
                        timeDiff = now - lastUpdate;
                        if (timeDiff > 0) {
                    /*force = Math.abs(x + y + z - lastX - lastY - lastZ)
                                / timeDiff;*/
                            force = Math.abs(x + y + z - lastX - lastY - lastZ);
                            if (Float.compare(force, threshold) >0 ) {
                                //Toast.makeText(Accelerometer.getContext(),
                                //(now-lastShake)+"  >= "+interval, 1000).show();
                                if (now - lastShake >= interval) {
                                    // trigger shake event
                                    listener.onShake(force);
                                }
                                else
                                {
                                    Toast.makeText(aContext,"No Motion detected",
                                            Toast.LENGTH_SHORT).show();
                                }
                                lastShake = now;
                            }
                            lastX = x;
                            lastY = y;
                            lastZ = z;
                            lastUpdate = now;
                        }
                        else
                        {
                            Toast.makeText(aContext,"No Motion detected", Toast.LENGTH_SHORT).show();
                        }
                    }
                    // trigger change event
                    listener.onAccelerationChanged(x, y, z);
                }
            };
}

خب امیدوارم با دیدن این کد ها نامید نشده باشید.در اینجا بخش اصلی کار ما در متد SensorEventListener انجام می شود که با تعریف تعدادی متغییر همراه است که وضعیت لرزش یا عدم لرزش به کمک ان ها انجام می شود.حالا میرسیم به اکتیویتی اصلیمان همانطور که قبلا گفتیم باید از رابط AccelerometerListener استفاده کنیم برای اینکار بصورت زیر عمل میکنیم و بقیه کد هارا هم مینویسیم:

public class MainActivity extends AppCompatActivity implements AccelerometerListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void onAccelerationChanged(float x, float y, float z) {
        // TODO Auto-generated method stub
    }
    public void onShake(float force) {
        // Do your stuff here
        // Called when Motion Detected
        Toast.makeText(getBaseContext(), "Motion detected",
                Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onResume() {
        super.onResume();
        Toast.makeText(getBaseContext(), "onResume Accelerometer Started",
                Toast.LENGTH_SHORT).show();
        //Check device supported Accelerometer senssor or not
        if (AccelerometerManager.isSupported(this)) {
            //Start Accelerometer Listening
            AccelerometerManager.startListening(this);
        }
    }
    @Override
    public void onStop() {
        super.onStop();
        //Check device supported Accelerometer senssor or not
        if (AccelerometerManager.isListening()) {
            //Start Accelerometer Listening
            AccelerometerManager.stopListening();
            Toast.makeText(getBaseContext(), "onStop Accelerometer Stoped",
                    Toast.LENGTH_SHORT).show();
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("Sensor", "Service  distroy");
        //Check device supported Accelerometer senssor or not
        if (AccelerometerManager.isListening()) {
            //Start Accelerometer Listening
            AccelerometerManager.stopListening();
            Toast.makeText(getBaseContext(), "onDestroy Accelerometer Stoped",
                    Toast.LENGTH_SHORT).show();
        }
    }
    }

خب همانطور که قبلا رابطی با نام AccelerometerListener ایجاد کردیم اکتیویتی اصلیمان را از ان implements  کردیم.سپس از متد هایonResume و onShake و onStop و onDestroy استفاده کردیم که با سه تای ان ها اشنایی پیدا کردیم در بحث اکتیویتی ها و متد onShake مبحث جدید میباشد که همانطور که از toast ان متوجه هستید هنگام تکان دادن گوشی عملیات داخل ان انجام می شود.
امیدوارم از اموزش لذت برده باشید و مفید بوده باشه.
موفق باشید..
 
 

مطالعه بیشتر