Menggunakan Accelerometer di Android
Indonesian (Bahasa Indonesia) translation by ⚡ Rova Rindrata (you can also view the original English article)
Menggunakan Accelerometer di AndroidDalam tutorial ini, kita akan mengeksplorasi cara menggunakan accelerometer, salah satu dari banyak sensor perangkat keras dari smartphone modern, dalam sebuah aplikasi Android. Saya akan menjelaskan apa itu accelerometer dan mengapa itu mungkin sesuatu yang Anda ingin manfaatkan dalam aplikasi Android Anda.
Perkenalan
Sebelum kemunculan smartphone, salah satu dari beberapa aplikasi komponen perangkat keras adalah dapat berinteraksi dengan keyboard. Tetapi waktu telah berubah dan berinteraksi dengan komponen perangkat keras menjadi semakin umum.
Menggunakan gerakan seringkali terasa lebih alami daripada berinteraksi dengan antarmuka pengguna melalui mouse dan keyboard. Ini terutama berlaku untuk perangkat sentuh, seperti smartphone dan tablet. Saya menemukan bahwa menggunakan gerakan dapat membawa aplikasi Android ke kehidupan, membuatnya lebih menarik dan menyenangkan bagi pengguna.
Dalam tutorial ini, kita akan menggunakan gerakan yang Anda temukan di beberapa aplikasi mobile, gerakan goyang. Kami akan menggunakan gerakan goyang untuk secara acak menghasilkan enam nomor Undian dan menampilkannya di layar menggunakan animasi yang cantik.
1. Persiapan
Langkah 1: Setup Proyek
Mulai proyek Android baru di IDE favorit Anda (Integrated Development Environment) untuk pengembangan Android. Untuk tutorial ini, saya akan menggunakan IntelliJ IDEA.
Jika IDE Anda mendukung pengembangan Android, itu akan menciptakan kelas Main
untuk Anda. Nama kelas ini dapat bervariasi tergantung pada IDE yang Anda gunakan. Kelas Main
memainkan peran kunci ketika aplikasi Anda diluncurkan. IDE Anda juga harus telah membuat file layout utama yang digunakan kelas Main
untuk membuat antarmuka pengguna aplikasi.
Karena kita akan menggunakan gerakan goyang, itu ide yang baik untuk mengunci orientasi perangkat. Ini akan memastikan bahwa antarmuka pengguna aplikasi tidak secara konstan beralih antara potret dan lansekap. Buka file manifest proyek dan tetapkan opsi screenOrientation
ke portrait
.
<activity android:name="com.Lottery.Main" android:screenOrientation="portrait" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
Langkah 2: Menyiapkan Sensor
Dengan penyiapan proyek kita, saatnya untuk bekerja dan menulis beberapa kode. Saat ini, kelas activity utama memiliki metode onCreate
di mana kita mengatur layout utama dengan menerapkan setContentView
seperti yang ditunjukkan di bawah ini.
public class Main extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Tergantung pada IDE yang Anda gunakan, Anda mungkin perlu menambahkan beberapa pernyataan import ke Main.java
, file tempat kelas Main
Anda berada. Kebanyakan IDE akan memasukkan pernyataan import ini untuk Anda, tetapi saya ingin memastikan bahwa kita berada di halaman yang sama sebelum melanjutkan. Pernyataan import pertama, import android.app.Activity
, mengimpor kelas Activity
sementara pernyataan import kedua, import android.os.Bundle
, mengimpor kelas Bundle
. Pernyataan import ketiga, com.example.R
, berisi definisi untuk sumber daya aplikasi. Pernyataan import ini akan berbeda dari yang Anda lihat di bawah karena tergantung pada nama paket Anda.
import android.app.Activity; import android.os.Bundle; import com.example.R;
Pada langkah berikutnya, kita akan memanfaatkan antarmuka SensorEventListener
, yang dideklarasikan di SDK Android. Untuk menggunakan antarmuka SensorEventListener
, kelas activity Main
perlu menerapkannya seperti yang ditunjukkan pada cuplikan kode di bawah ini. Jika Anda melihat kelas activity Main
yang diperbarui, Anda akan menemukan bahwa saya menggunakan kata kunci implements
untuk memberitahu compiler bahwa kelas Main
mengimplementasikan antarmuka SensorEventListener
.
public class Main extends Activity implements SensorEventListener { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Untuk menggunakan antarmuka SensorEventListener
, Anda perlu menambahkan pernyataan import lain seperti yang ditunjukkan di bawah ini. Kebanyakan IDE secara cerdas akan menambahkan pernyataan import untuk Anda sehingga Anda mungkin tidak perlu khawatir tentang hal ini.
import android.hardware.SensorEventListener;
Mulai saat ini, Anda memperbarui implementasi kelas Main
seperti yang ditunjukkan di atas, Anda akan melihat beberapa kesalahan muncul. Ini tidak mengherankan karena kita perlu menerapkan dua metode yang diperlukan dari antarmuka SensorEventListener
.
Jika Anda menggunakan IntelliJ IDEA, Anda harus diminta untuk menambahkan metode yang diperlukan ini ketika Anda mengklik kesalahan. Jika Anda menggunakan IDE yang berbeda, perilaku ini mungkin berbeda. Mari tambahkan dua metode yang diperlukan dengan tangan seperti yang ditunjukkan pada cuplikan kode di bawah ini. Pastikan untuk menambahkan metode-metode ini di kelas Main
dan di luar metode onCreate
.
@Override public void onSensorChanged(SensorEvent event) { } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { }
Mari kita lihat metode onSensorChanged
. Kita akan menggunakan metode ini untuk mendeteksi gerakan goyang. Metode onSensorChanged
dipanggil setiap kali sensor internal mendeteksi perubahan. Metode ini dipanggil berulang kali setiap kali perangkat sedang bergerak. Untuk menggunakan kelas Sensor
dan SensorEvent
, kita menambahkan dua pernyataan import tambahan seperti yang ditunjukkan di bawah ini.
import android.hardware.Sensor; import android.hardware.SensorEvent;
Sebelum kita menerapkan onSensorChanged
, kita perlu mendeklarasikan dua variabel private di kelas Main
, senSensorManager
dari jenis SensorManager
dan senAccelerometer
dari jenis Sensor
.
private SensorManager senSensorManager; private Sensor senAccelerometer;
Kelas SensorManager
dideklarasikan di android.hardware.SensorManager
. Jika Anda melihat kesalahan muncul, periksa kembali bahwa kelas SensorManager
juga diimpor.
import android.hardware.SensorManager;
Dalam metode onCreate
, kita menginisialisasi variabel yang baru saja kita nyatakan dan mendaftarkan listener. Lihatlah penerapan metode onCreate
yang diperbarui.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_NORMAL); }
Untuk menginisialisasi instance SensorManager
, kita meminta getSystemService
untuk mengambil instance SensorManager
dari sistem, yang pada gilirannya kita gunakan untuk mengakses sensor dari sistem. Metode getSystemService
digunakan untuk mendapatkan referensi ke layanan dari sistem dengan mengirimkan nama layanannya. Dengan sensor manager yang kita miliki, kita mendapatkan referensi untuk accelerometer sistem dengan memanggil getDefaultSensor
pada manajer sensor dan melewatkan jenis sensor yang kita minati. Kita kemudian mendaftarkan sensor menggunakan salah satu metode public SensorManager
, registerListener
. Metode ini menerima tiga argumen, konteks activity, sensor, dan tingkat di mana event sensor dikirimkan kepada kita.
public class Main extends Activity implements SensorEventListener { private SensorManager senSensorManager; private Sensor senAccelerometer; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_NORMAL); } @Override public void onSensorChanged(SensorEvent sensorEvent) { } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }
Ada dua metode lain yang perlu kita ganti, onPause
dan onResume
. Ini adalah metode kelas Main
. Ini adalah praktik yang baik untuk membatalkan pendaftaran sensor ketika aplikasi berhibernasi dan mendaftarkan sensor lagi ketika aplikasi dilanjutkan. Lihatlah cuplikan kode di bawah ini untuk mendapatkan gagasan tentang cara kerjanya dalam praktiknya.
protected void onPause() { super.onPause(); senSensorManager.unregisterListener(this); }
protected void onResume() { super.onResume(); senSensorManager.registerListener(this, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); }
Langkah 3: Mendeteksi Gerakan Goyang
Kita sekarang dapat mulai fokus pada isi aplikasinya. Ini akan membutuhkan sedikit matematika untuk mencari tahu kapan gerakan goyang terjadi. Sebagian besar logika akan masuk ke metode onSensorChanged
. Kita mulai dengan mendeklarasikan beberapa variabel di kelas Main
kita. Lihatlah cuplikan kode di bawah ini.
private long lastUpdate = 0; private float last_x, last_y, last_z; private static final int SHAKE_THRESHOLD = 600;
Sekarang mari kita berfokus pada penerapan metode onSensorChanged
. Kita mengambil referensi ke instance Sensor
menggunakan instance SensorEvent
yang dilewatkan kepada kita. Seperti yang Anda lihat di cuplikan kode di bawah ini, kita memeriksa kembali bahwa kita mendapatkan referensi ke jenis sensor yang benar, accelerometer dari sistem.
public void onSensorChange(SensorEvent sensorEvent) { Sensor mySensor = sensorEvent.sensor; if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) { } }
Langkah selanjutnya adalah mengekstrak posisi perangkat dalam ruang, sumbu x
, y
, dan z
. Lihatlah gambar di bawah ini untuk lebih memahami apa yang saya maksud. Sumbu x
mendefinisikan gerakan lateral, sedangkan sumbu y
mendefinisikan gerakan vertikal. Sumbu z
sedikit rumit karena mendefinisikan gerakan masuk dan keluar dari bidang yang ditentukan oleh sumbu x
dan y
.



Untuk mendapatkan nilai masing-masing sumbu, kita meminta event sensor untuk nilainya seperti yang ditunjukkan di bawah ini. Atribut values
event adalah array dari float.
public void onSensorChange(SensorEvent sensorEvent) { Sensor mySensor = sensorEvent.sensor; if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) { float x = sensorEvent.values[0]; float y = sensorEvent.values[1]; float z = sensorEvent.values[2]; } }
Sensor sistem sangat sensitif. Ketika memegang perangkat di tangan Anda, itu terus bergerak, tidak peduli seberapa stabil tangan Anda. Hasilnya adalah bahwa metode onSensorChanged
dipanggil beberapa kali per detik. Kita tidak memerlukan semua data ini sehingga kita perlu memastikan bahwa kita hanya mengambil sampel sebagian data yang kita peroleh dari accelerometer perangkat. Kita menyimpan waktu sistem saat ini (dalam milidetik) menyimpannya dalam curTime
dan memeriksa apakah lebih dari 100
milidetik telah berlalu sejak terakhir kali pada onSensorChanged
dipanggil.
public void onSensorChange(SensorEvent sensorEvent) { Sensor mySensor = sensorEvent.sensor; if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) { float x = sensorEvent.values[0]; float y = sensorEvent.values[1]; float z = sensorEvent.values[2]; long curTime = System.currentTimeMillis(); if ((curTime - lastUpdate) > 100) { long diffTime = (curTime - lastUpdate); lastUpdate = curTime; } } }
Bagian terakhir dari teka-tekinya adalah mendeteksi apakah perangkat telah terguncang atau tidak. Kita menggunakan kelas Math
untuk menghitung kecepatan perangkat seperti yang ditunjukkan di bawah ini. Variabel SHAKE_THRESHOLD
yang dinyatakan secara static digunakan untuk melihat apakah gerakan goyang telah terdeteksi atau tidak. Memodifikasi SHAKE_THRESHOLD
meningkatkan atau menurunkan sensitivitas sehingga silakan untuk bermain dengan nilainya.
public void onSensorChange(SensorEvent sensorEvent) { Sensor mySensor = sensorEvent.sensor; if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) { float x = sensorEvent.values[0]; float y = sensorEvent.values[1]; float z = sensorEvent.values[2]; long curTime = System.currentTimeMillis(); if ((curTime - lastUpdate) > 100) { long diffTime = (curTime - lastUpdate); lastUpdate = curTime; float speed = Math.abs(x + y + z - last_x - last_y - last_z)/ diffTime * 10000; if (speed > SHAKE_THRESHOLD) { } last_x = x; last_y = y; last_z = z; } } }
2. Menyelesaikan Aplikasi Undian
Kita sekarang memiliki aplikasi yang dapat mendeteksi gerakan goyang menggunakan accelerometer. Mari kita selesaikan proyek ini dengan menggunakan gerakan goyang untuk memilih enam nomor undian acak. Saya akan menunjukkan kepada Anda cara menghasilkan nomor acak antara 1
dan 49
, tetapi Anda bebas memodifikasi implementasi saya untuk membuatnya bekerja dengan cara undian dimainkan di negara Anda.
Mari kita mulai dengan mengatur file layout main aplikasi yang akan kita gunakan untuk antarmuka pengguna. Seperti yang Anda lihat di bawah, saya menggunakan enam layout bingkai dengan latar belakang gambar bola.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:layout_height="wrap_content" android:layout_width="fill_parent" android:weightSum="6" android:orientation="horizontal"> <FrameLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="5dp" android:layout_weight="2" android:id="@+id/ball_1" android:background="@drawable/blue"> <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/number_1" android:gravity="center" android:layout_gravity="center_vertical" android:textColor="@android:color/white"/> </FrameLayout> <FrameLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="5dp" android:layout_weight="2" android:id="@+id/ball_2" android:background="@drawable/blue"> <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/number_2" android:gravity="center" android:layout_gravity="center_vertical" android:textColor="@android:color/white"/> </FrameLayout> <FrameLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="5dp" android:layout_weight="2" android:id="@+id/ball_3" android:background="@drawable/blue"> <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/number_3" android:gravity="center" android:layout_gravity="center_vertical" android:textColor="@android:color/white"/> </FrameLayout> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="fill_parent" android:weightSum="6" android:orientation="horizontal"> <FrameLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="5dp" android:layout_weight="2" android:id="@+id/ball_4" android:background="@drawable/blue"> <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/number_4" android:gravity="center" android:layout_gravity="center_vertical" android:textColor="@android:color/white"/> </FrameLayout> <FrameLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="5dp" android:id="@+id/ball_5" android:layout_weight="2" android:background="@drawable/blue"> <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/number_5" android:gravity="center" android:layout_gravity="center_vertical" android:textColor="@android:color/white"/> </FrameLayout> <FrameLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_margin="5dp" android:id="@+id/ball_6" android:layout_weight="2" android:background="@drawable/blue"> <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/number_6" android:gravity="center" android:layout_gravity="center_vertical" android:textColor="@android:color/white"/> </FrameLayout> </LinearLayout> </LinearLayout>
Setiap layout bingkai berisi text view yang akan menampilkan nomor undian yang dihasilkan secara acak. Perhatikan bahwa setiap layout bingkai dan text view memiliki id
untuk memastikan bahwa kita dapat mereferensikannya nanti.
Dengan layout main siap digunakan, mari kembali ke kelas Main
. Kita mulai dengan membuat getRandomNumber
, metode private untuk menghasilkan enam angka acak antara 1
dan 49
.
private void getRandomNumber() { ArrayList numbersGenerated = new ArrayList(); for (int i = 0; i < 6; i++) { Random randNumber = new Random(); int iNumber = randNumber.nextInt(48) + 1; if(!numbersGenerated.contains(iNumber)) { numbersGenerated.add(iNumber); } else { i--; } } }
Kita pertama kali membuat instance ArrayList
, yang kita gunakan untuk menyimpan enam angka di dalamnya. Di setiap perulangan dari perulangan for
, kita memanfaatkan kelas Random
Java untuk menghasilkan nomor acak. Untuk memastikan bahwa kita mendapatkan angka antara 1
dan 49
, kita menambahkan 1
ke hasilnya. Langkah selanjutnya adalah memeriksa apakah nomor yang dihasilkan sudah ada dalam daftar array, karena kita hanya ingin nomor unik dalam daftar array.
Perhatikan bahwa mungkin perlu menambahkan dua pernyataan import lagi untuk menjaga compiler tetap senang.
import java.util.ArrayList; import java.util.Random;
Langkah terakhir adalah menampilkan nomor yang dihasilkan secara acak di antarmuka pengguna. Kita mendapatkan referensi ke text view yang kita buat sebelumnya dan mengisi setiap text view dengan nomor acak. Kita juga menambahkan animasi yang rapi ke layout bingkai, tetapi jangan ragu untuk menghilangkan atau memodifikasi animasinya.
private void getRandomNumber() { ArrayList numbersGenerated = new ArrayList(); for (int i = 0; i < 6; i++) { Random randNumber = new Random(); int iNumber = randNumber.nextInt(48) + 1; if(!numbersGenerated.contains(iNumber)) { numbersGenerated.add(iNumber); } else { i--; } } TextView text = (TextView)findViewById(R.id.number_1); text.setText(""+numbersGenerated.get(0)); text = (TextView)findViewById(R.id.number_2); text.setText(""+numbersGenerated.get(1)); text = (TextView)findViewById(R.id.number_3); text.setText(""+numbersGenerated.get(2)); text = (TextView)findViewById(R.id.number_4); text.setText(""+numbersGenerated.get(3)); text = (TextView)findViewById(R.id.number_5); text.setText(""+numbersGenerated.get(4)); text = (TextView)findViewById(R.id.number_6); text.setText(""+numbersGenerated.get(5)); FrameLayout ball1 = (FrameLayout) findViewById(R.id.ball_1); ball1.setVisibility(View.INVISIBLE); FrameLayout ball2 = (FrameLayout) findViewById(R.id.ball_2); ball2.setVisibility(View.INVISIBLE); FrameLayout ball3 = (FrameLayout) findViewById(R.id.ball_3); ball3.setVisibility(View.INVISIBLE); FrameLayout ball4 = (FrameLayout) findViewById(R.id.ball_4); ball4.setVisibility(View.INVISIBLE); FrameLayout ball5 = (FrameLayout) findViewById(R.id.ball_5); ball5.setVisibility(View.INVISIBLE); FrameLayout ball6 = (FrameLayout) findViewById(R.id.ball_6); ball6.setVisibility(View.INVISIBLE); Animation a = AnimationUtils.loadAnimation(this, R.anim.move_down_ball_first); ball6.setVisibility(View.VISIBLE); ball6.clearAnimation(); ball6.startAnimation(a); ball5.setVisibility(View.VISIBLE); ball5.clearAnimation(); ball5.startAnimation(a); ball4.setVisibility(View.VISIBLE); ball4.clearAnimation(); ball4.startAnimation(a); ball3.setVisibility(View.VISIBLE); ball3.clearAnimation(); ball3.startAnimation(a); ball2.setVisibility(View.VISIBLE); ball2.clearAnimation(); ball2.startAnimation(a); ball1.setVisibility(View.VISIBLE); ball1.clearAnimation(); ball1.startAnimation(a); }
Kita perlu menambahkan beberapa pernyataan import untuk membuat semua ini berfungsi. Lihatlah cuplikan kode di bawah ini.
import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; import android.widget.TextView;
Untuk animasinya, lihat isi file animation di bawah ini. Perhatikan bahwa Anda perlu membuat folder anim
di direktori sumber daya proyek Anda dan beri nama move_down_ball_first.xml
. Dengan menyesuaikan nilai elemen scale
, Anda dapat memodifikasi durasi animasi dan posisi setiap bola.
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" android:interpolator="@android:anim/bounce_interpolator"> <scale android:duration="1500" android:fromXScale="1.0" android:fromYScale="-10.0" android:toXScale="1.0" android:toYScale="1.0" /> </set>
Semua yang tersisa untuk kita lakukan adalah memanggil getRandomNumber
di onSensorChanged
di kelas Main
. Lihatlah implementasi lengkap dari onSensorChanged
yang ditunjukkan di bawah ini.
public void onSensorChange(SensorEvent sensorEvent) { Sensor mySensor = sensorEvent.sensor; if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) { float x = sensorEvent.values[0]; float y = sensorEvent.values[1]; float z = sensorEvent.values[2]; long curTime = System.currentTimeMillis(); if ((curTime - lastUpdate) > 100) { long diffTime = (curTime - lastUpdate); lastUpdate = curTime; float speed = Math.abs(x + y + z - last_x - last_y - last_z)/ diffTime * 10000; if (speed > SHAKE_THRESHOLD) { getRandomNumber(); } last_x = x; last_y = y; last_z = z; } } }

Kesimpulan
Dalam tutorial ini, saya telah menunjukkan kepada Anda bagaimana accelerometer bekerja dan bagaimana Anda dapat menggunakannya untuk mendeteksi gerakan goyang. Tentu saja, ada banyak kasus penggunaan lain untuk accelerometer. Dengan pemahaman dasar untuk mendeteksi gerakan menggunakan accelerometer, saya mendorong Anda untuk bereksperimen dengan accelerometer untuk melihat apa lagi yang dapat Anda lakukan dengannya.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weekly