آموزش Shake زدن - خیلی راحت و سریع
تا اینجا بازدهی و تشکر های بچه ها و نظراتی که دادند واقعا خوب بوده ، اگه همین روند ادامه داشته باشه یه آموزش باحال دیگه رو هم روی سایت قرار میدم که خیلی برای خوده من جالب و کاربردی بود.
ممنون از همه دوستان
با سلام
اول از همه از همه بچه های سایت آنکو معذرت خواهی می کنم (بدلیل پست قبلی) و اینم باید بگم دلیل این رفتار آشنا نبودن من با روش ارائه آموزش در این سایت بود.
دوما هم باید بگم ممنون از تذکر دوستان و استاد آقاجانی و اینکه حتما تذکرات دوستان رو مورد توجه قرار میدم و طبق قوانین سایت پیش میرم.
نکته سوم هم این که مجددا از تمام دوستان عذرخواهی می کنم. :)))
0. مقدمه :
قبل از شروع آموزش می خوام در مورد اینکه من چجوری shake زدن رو یادگرفتم توضیح بدم تا دوستانی که تازه شروع کردن از این روش استفاده کنند و انتظار نداشته باشند که جواب همه سوالاشون رو توی این سایت پیدا می کنند.
1. چجوری من shake زدن رو یاد گرفتم؟
راستش برای یکی از پروژه هام نیاز به این قابلیت داشتم ، اصلا هم بلد نبودم چطوریه ، تو انجمن خودمون چیزی پیدا نکردم ، پس خودم دست به کار شدم ، اول آموزش استاد در خصوص کار با سنسورها رو تماشا کردم ، بعد رفتم سراغ stackoverflow.com fh ;ld با کمی اینور اونور کردم آخر به یه جواب درست و بدرد بخور رسیدم ، پس کدهای جواب رو داخل پروژم کپی کردم و تست کردم ، کاملا کار می کرد ولی حساسیتش اصلا باب میلم نبود دوما بعضی وقتها که قوی shake میزدی 2 تا شیک حساب می کردم ، کمی باهاش کانجار رفتم تا آخر شد همونی که خودم می خوام.
در مرحله آخر هم خدا رو شکر کردم که کمکم کرد به علمم اضافه کنم.
2. آیا پیاده سازی قابلیت shake داخل پروژه سخته؟
اصلا ، کلیت کار به این صورته که یه کلاس که کار شناسایی عمل shake رو داره رو داخل پروژتون وارد می کنید و در اکتیویتی مورد نظر متد onShake رو رونویسی می کنید.
3. نمی خوای بس کنی و آموزش رو شروع کنی؟
:)) ، دقیقا الان می خواستم همین کار رو بکنم.
یه نکته بچه ها ، اگه واقعا بازتاب این آموزش خوب باشه حتما این روند رو ادامه میدم. ( منظورم این نست که لایک کنید تا من امتیاز بگیرم ، منظورم اینه که بفهمم این آموزش بدرد دیگران خورد و مخاطب خودش رو داشت.)
با تشکر
حمید زمانی

4. بدون اینکه ذهتون رو درگیره چیزی کنید یه فایل جاوا با نام ShakeDetector ایجاد کنید و کدهای زیر رو داخلش کپی کنید:
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.util.Log;
public class ShakeDetector implements SensorEventListener {
// Minimum acceleration needed to count as a shake movement
private static final int MIN_SHAKE_ACCELERATION = 5;
// Minimum number of movements to register a shake
private static final int MIN_MOVEMENTS = 2;
// Maximum time (in milliseconds) for the whole shake to occur
private static final int MAX_SHAKE_DURATION = 500;
// Arrays to store gravity and linear acceleration values
private float[] mGravity = {0.0f, 0.0f, 0.0f};
private float[] mLinearAcceleration = {0.0f, 0.0f, 0.0f};
// Indexes for x, y, and z values
private static final int X = 0;
private static final int Y = 1;
private static final int Z = 2;
// OnShakeListener that will be notified when the shake is detected
private OnShakeListener mShakeListener;
// Start time for the shake detection
long startTime = 0;
// Counter for shake movements
int moveCount = 0;
//my variable
long lastShake;
long different = 0;
// Constructor that sets the shake listener
public ShakeDetector(OnShakeListener shakeListener) {
mShakeListener = shakeListener;
}
@Override
public void onSensorChanged(SensorEvent event) {
// This method will be called when the accelerometer detects a change.
// Call a helper method that wraps code from the Android developer site
setCurrentAcceleration(event);
// Get the max linear acceleration in any direction
float maxLinearAcceleration = getMaxCurrentLinearAcceleration();
// Check if the acceleration is greater than our minimum threshold
if (maxLinearAcceleration > MIN_SHAKE_ACCELERATION) {
long now = System.currentTimeMillis();
// Set the startTime if it was reset to zero
if (startTime == 0) {
startTime = now;
}
long elapsedTime = now - startTime;
Log.e("shake", "now : " + now + " | startTime : " + startTime + " | elapsedTime : " + elapsedTime);
// Check if we're still in the shake window we defined
if (elapsedTime > MAX_SHAKE_DURATION) {
// Too much time has passed. Start over!
resetShakeDetection();
} else {
// Keep track of all the movements
moveCount++;
// Check if enough movements have been made to qualify as a shake
if (moveCount > MIN_MOVEMENTS) {
different = now - lastShake;
if (different > 500 || different == 0) {
Log.e("shake", "different : " + different);
lastShake = now;
// It's a shake! Notify the listener.
mShakeListener.onShake();
// Reset for the next one!
resetShakeDetection();
}
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Intentionally blank
}
private void setCurrentAcceleration(SensorEvent event) {
/*
* BEGIN SECTION from Android developer site. This code accounts for
* gravity using a high-pass filter
*/
// alpha is calculated as t / (t + dT)
// with t, the low-pass filter's time-constant
// and dT, the event delivery rate
final float alpha = 0.8f;
// Gravity components of x, y, and z acceleration
mGravity[X] = alpha * mGravity[X] + (1 - alpha) * event.values[X];
mGravity[Y] = alpha * mGravity[Y] + (1 - alpha) * event.values[Y];
mGravity[Z] = alpha * mGravity[Z] + (1 - alpha) * event.values[Z];
// Linear acceleration along the x, y, and z axes (gravity effects removed)
mLinearAcceleration[X] = event.values[X] - mGravity[X];
mLinearAcceleration[Y] = event.values[Y] - mGravity[Y];
mLinearAcceleration[Z] = event.values[Z] - mGravity[Z];
/*
* END SECTION from Android developer site
*/
}
private float getMaxCurrentLinearAcceleration() {
// Start by setting the value to the x value
float maxLinearAcceleration = mLinearAcceleration[X];
// Check if the y value is greater
if (mLinearAcceleration[Y] > maxLinearAcceleration) {
maxLinearAcceleration = mLinearAcceleration[Y];
}
// Check if the z value is greater
if (mLinearAcceleration[Z] > maxLinearAcceleration) {
maxLinearAcceleration = mLinearAcceleration[Z];
}
// Return the greatest value
return maxLinearAcceleration;
}
private void resetShakeDetection() {
startTime = 0;
moveCount = 0;
}
// (I'd normally put this definition in it's own .java file)
public interface OnShakeListener {
public void onShake();
}
}
توضیحات :
نکته : من نمی تونم مثل استاد آقاجانی مو به مو و عالی براتون توضیح بدم. :))
MIN_SHAKE_ACCELERATION : این متغیر برای تعیین حداقل میزان شدت حرکت می باشد.(مثلا با یه لرزش کوچیک shake حساب نکنه)
قسمت مهم دیگه این کد هم کد زیر هست :
different = now - lastShake;
if (different > 500 || different == 0) {
Log.e("shake", "different : " + different);
lastShake = now;
// It's a shake! Notify the listener.
mShakeListener.onShake();
// Reset for the next one!
resetShakeDetection();
}
یه متغیر از نوع long داریم که تفاوت زمان آخرین شیک با زمان حال (همین لحظه) رو مسنجیم ، این قسمت برای اینه که اگه کاربر قوی شد 2 یا 3 تا shake حساب نشه ، من تو این کد گفتم اگه تفاوت زمانی از یه مقداری (در اینجا 500 میلی ثانیه) کمتر بود ، shake حساب نکن.
این کد قسمت های زیادی داره که میشه شخصی سازی و دستکاریش کرد ولی برای پیاده سازی یه shake ساده همین توضیحاتی که دادم کافیه و با همینا کار راه میافته ، البته دوستان اگه اطلاعات بیشتر و توضیحات بیشتری دارید می تونید ارائه کنید تا ما هم استفاده کنیم.

5. خوب تا اینجا کلاس ShakeDetector رو داریم ، پس این کلاس رو وارد پروژتون کنید ، در مرحله ی بعدی میریم سراغ اکتویتی ای که می خوام توش قابلیت shake رو پیاده سازی کنیم.
بالا onCreate فیلد های زیر رو کپی کنید :
private ShakeDetector mShakeDetector;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
داخل onCreate کد های زیر رو کپی کنید :
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mShakeDetector = new ShakeDetector(new ShakeDetector.OnShakeListener() {
@Override
public void onShake() {
Log.e("shake", "onShake");
}
});
خارج از onCreate متد های زیر رو کپی کنید :
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}
@Override
protected void onPause() {
mSensorManager.unregisterListener(mShakeDetector);
super.onPause();
}
توضیحات :
اگه آموزش استاد در خصوص سنوسر ها رو دیده باشین توضیح خاصی نداره این بخش ، فقط در متد ها onPause و onResume اتصال به سنسور رو قطع و وصل می کنیم تا در صورتی که در داخل برنامه نبودیم یا نیازی به این سنسور نداشتیم از مصرف زیاد باتری جلوگیری کنیم و دوما اینکه راه اصولیش اینه.
تمام شد ، شما الان میتونید shake بزنید. :))
فقط نکته آخر اینکه یه shake هم واس من بزنید. (خخخخخخ)

ضمن سلام از همه دوستان ، من تازه یکی دو هفته برنامه نویسی اندروید شروع کردم
یک سایت آموزشی زدم به آدرس http://kianlearning.ir
خوشحال میشم هر کس آموزشی یا چیزی داره اونجا هم قرار بده ،
البته سایت و هنوز یک هفته نشده آپ کردم ، و هنوز هم کامل نیست ،
خیلی از قسمت هاش کار نمیکنه . دارم کم کم کامل میکنم
ولی قسمت قرار دادن پروژه و عضویت کار میکنه ، لطفا اونجا هم آموزش بزارین . هر آموزشی بلدین
ضمنا اگر کسی توانایی و وقت شو داره خوشحال میشم تو سایتم کمک کنه به من
www.kianlearning.ir
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .