بسم الله الرحمن الرحيم
والصلاة والسلام على أشرف الأنبياء والمرسلين
سيدنا محمد وعلى آله وصحبه أجمعين..
تطبيق البوصلة أحد التطبيقات المهمة التي نحتاج إليها في الكثير من البرامج، سواءً كان هذا التطبيق منفصلاً أو كان جزءاً من تطبيق أوسع مثل بعض التطبيقات
الإسلامية التي تساعد على معرفة اتجاه القبلة أو أوقات الصلوات وما شابه ذلك.
لنخض في الموضوع مباشرة.
افتح مشروعاً جديداً في اندرويد استوديو من قائمة ملف ثم قم بتسمية المشروع كما تريد، ثم ابدأ بالإجراءات التالية :
أولاً لعمل تطبيق بوصلة نحن نحتاج إلى اثنين من الاستشعارات :
Accelerometer sensor, Magento motor sensor
إذا كان جهازك يحتوي على هذين الاستشعارين فسيعمل تطبيق البوصلة عندك بكل سهولة، ودون مشاكل.
سوف نستعمل منطقة استشعارالتسارع Accelerometer sensor مع مستشعر المحرك المغناطيسي Magento motor
sensor وسنحصل على مصفوفة الدوران Rotation matrix، ومن ثم سنحصل على الإتجاه Orientation.
لكي لا نطيل الشرح وتتعقد عليكم بعض الأمور دعنا نخض في الشفرة مباشرة .
أولاً : ينبغي عليك أن تتحصل على صور مثل الصور المرفقة التالية ثم تقوم بتجهيزها كما ينبغي وتقوم بتسميتها بالشكل الصحيح ووضعها داخل مجلد drawable.
ضع هاتين الصورتين داخل مجلد drawable وقم بتسميتهم على التوالي بالاسماء التالية :
compass33.png,
compass4.png
طبعاً بإمكانك تغيير كل هذه الأسماء وأيضاً الصور يمكنك أن تختار ما تشاء ولكن يفضل عمل ذلك بعد تجربة هذه الشفرة كما هي حتى لا تواجهك اخطاء بسيطة تأخذ من وقتك الكثير.
ثانياً : نحتاج لعمل ملف xml Activity
وليكن باسم activity_main_compass2.xml
ثم نكتب فيه الشفرة التالية :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/backgnd"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
app:srcCompat="@android:color/black" />
<ImageView
android:id="@+id/imgBasicCompass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@drawable/compass33" />
<ImageView
android:id="@+id/imageViewCompass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@drawable/compass4" />
</RelativeLayout>
ثالثاً : نتوجه إلى الشفرة الرئيسية وهي Activity Main java ونكتب الكود التالي:
تحت اسم التطبيق داخل ال acitivity انسخ والصق الكود التالي :
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivityCompass extends AppCompatActivity implements SensorEventListener{
private ImageView imageView;
private float[] mGravity = new float[3];
private float[] mGeoMagnetic = new float[3];
private float azimuth=0f;
private float currentAzimuth =0f;
private SensorManager mSensorManager;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_compass2);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
imageView = findViewById(R.id.imageViewCompass);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
}
@Override
protected void onResume(){
super.onResume();
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
final float alpha= 0.97f;
synchronized (this) {
if(sensorEvent.sensor.getType()== Sensor.TYPE_ACCELEROMETER) {
mGravity[0]=alpha*mGravity[0]+(1-alpha)*sensorEvent.values[0];
mGravity[1]=alpha*mGravity[1]+(1-alpha)*sensorEvent.values[1];
mGravity[2]=alpha*mGravity[2]+(1-alpha)*sensorEvent.values[2];
}
if(sensorEvent.sensor.getType()== Sensor.TYPE_MAGNETIC_FIELD) {
mGeoMagnetic[0]=alpha*mGeoMagnetic[0]+(1-alpha)*sensorEvent.values[0];
mGeoMagnetic[1]=alpha*mGeoMagnetic[1]+(1-alpha)*sensorEvent.values[1];
mGeoMagnetic[2]=alpha*mGeoMagnetic[2]+(1-alpha)*sensorEvent.values[2];
}
float R[] = new float[9];
float I[] = new float[9];
boolean succsess = SensorManager.getRotationMatrix(R,I,mGravity,mGeoMagnetic);
if(succsess){
float orientation[] = new float[3];
SensorManager.getOrientation(R,orientation);
azimuth = (float)Math.toDegrees(orientation[0]);
azimuth = (azimuth + 360)%360;
Animation anim = new RotateAnimation(-currentAzimuth, -azimuth, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);
currentAzimuth = azimuth;
anim.setDuration(500);
anim.setRepeatCount(0);
anim.setFillAfter(true);
imageView.startAnimation(anim);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
والآن يمكنك أن تقوم بتجربة المشروع على جوالك والاستمتاع به وإذا كانت لديك ملاحظات أو تحسينات على المشروع الرجاء كتابتها في التعليقات لتعم الفائدة على الجميع.
وللمزيد من الشرح ومعرفة التفاصيل عن ما تم كتابته في الشفرة يرجى الرجوع إلى المرجع الأساسي