إعداد البرنامج التجريبي

يستخدم تقييم الأجهزة البرامج التالية:

  • Audacity (مثبَّت على الكمبيوتر)
  • MATLAB (مثبَّت على الكمبيوتر الشخصي)
  • تطبيق اختبار تقنية "اللمس" (مثبَّت على جهاز الاختبار)

لمعرفة المزيد من المعلومات عن متطلبات النظام، يُرجى الاطّلاع على Audacity لنظام التشغيل Windows وAudacity لنظام التشغيل Mac وMATLAB.

إعداد Audacity

يجب إعداد Audacity لتلقّي الإدخال من بطاقة الصوت Sound Blaster بمعدّل قياس معيّن للبيانات. بعد توصيل Sound Blaster بمنفذ USB في الكمبيوتر، افتح Audacity واتّبِع التعليمات التالية.

  1. اختَر Line (USB Sound Blaster HD) كمصدر لميكروفون الإدخال من خلال توصيل إخراج CCLD بمنفذ إدخال Line In في Sound Blaster.

    إدخال الميكروفون

    الشكل 1. جارٍ اختيار إدخال الميكروفون

  2. اضبط معدّل أخذ العيّنات على 48 كيلوهرتز من خلال اختيار 48,000 في القائمة معدّل المشروع.

    معدّل البيانات في الملف الصوتي

    الشكل 2: تحديد معدل أخذ العينات

تنزيل MATLAB

  1. نزِّل ملف MATLAB .

  2. استخرِج الملف وابحث عن Effect1NEffect2_V1p0_2020PM.m (بالنسبة إلى Effect1 وEffect 2) وEffect3_V1p0_2020PM.m (بالنسبة إلى التأثير 3).

إعداد التطبيق التجريبي على الهاتف

يصف هذا القسم طريقة إعداد التطبيق التجريبي على الهاتف.

الاستعداد للتطبيق التجريبي

  1. انسخ رمز المصدر من مجموعات رموز Java وKotlin أدناه. اختَر الطريقة الأنسب لك.
  2. اكتب التعليمة البرمجية باتباع معلمات واجهة المستخدم الرسومية الموضحة في الشكل 3. اضبط تفاصيل رمز مصدر التصميم لتتطابق مع هاتفك إذا لزم الأمر.
  3. تأكَّد من أنّ واجهة المستخدم تتضمّن ثلاثة أزرار يمكن النقر عليها ومقياس رسومي لتحديد المنطقة التي سيتم تحديد موضع مقياس التسارع فيها.

    • تمثّل منطقة تحديد موقع أداة التسارع المساحة الحقيقية لشاشة الجهاز التي يتم لمسها عادةً باليد.
    • أثناء هذا القياس، يمكنك تحريك مقياس التسارع ضمن المنطقة الخضراء الزاهية للعثور على منطقة الشاشة التي تلتقط الإشارة الأقوى.
  4. ثبِّت الرمز على جهاز Android.

  5. يوصى بشدة بتعيين وضع التنقل داخل النظام على وضع الإيماءة إذا تم تعيين الوضع الافتراضي كأزرار.

    • من خلال ضبط وضع الإيماءات، يمكنك وضع أداة التسارع في أسفل الهاتف قدر الإمكان بدون أن تقاطعك واجهات المستخدم الرسومية لتنقّل النظام في الهاتف.

رمز مصدر Java

package com.example.hapticeffectassessment;

import static android.os.VibrationEffect.EFFECT_CLICK;

import android.graphics.Color;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

 private static final long oneShotTiming = 20;
 private static final int oneShotAmplitude = 255;

 private static final long[] waveformTimings = {500, 500};
 private static final int[] waveformAmplitudes = {128, 255};

 @Override
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);

   Vibrator vibrator = getSystemService(Vibrator.class);

   // Click R.id.button1 button to generate Effect 1
   findViewById(R.id.button1).setOnClickListener(
       view -> vibrator.vibrate(VibrationEffect.createPredefined(EFFECT_CLICK)));

   // Click R.id.button2 button to generate Effect 2
   findViewById(R.id.button2).setOnClickListener(
       view -> vibrator.vibrate(VibrationEffect.createOneShot(oneShotTiming, oneShotAmplitude)));

   // Click R.id.button3 button to generate Effect 3
   findViewById(R.id.button3).setOnClickListener(view -> {
     vibrator.vibrate(VibrationEffect.createWaveform(waveformTimings, waveformAmplitudes, -1));

     // See quick results of Effect 3
     Button button = (Button) view;
     if (vibrator.hasAmplitudeControl()) {
       button.setText("Effect 3: PASS");
       button.setBackgroundColor(Color.GREEN);
       button.setTextColor(Color.BLACK);
     } else {
       button.setText("Effect 3: FAIL");
       button.setBackgroundColor(Color.RED);
       button.setTextColor(Color.WHITE);
     }
   });
 }
}

رمز مصدر Kotlin

package com.example.hapticeffectassessment

import android.graphics.Color
import android.os.Bundle
import android.os.VibrationEffect
import android.os.VibrationEffect.EFFECT_CLICK
import android.os.Vibrator
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivityKt : AppCompatActivity() {

 private val oneShotTiming: Long = 20
 private val oneShotAmplitude = 255

 private val waveformTimings = longArrayOf(500, 500)
 private val waveformAmplitudes = intArrayOf(128, 255)

 override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val vibrator = getSystemService(Vibrator::class.java)

   // Click button1 to generate Effect 1
   button1.setOnClickListener {
     vibrator.vibrate(VibrationEffect.createPredefined(EFFECT_CLICK))
   }

   // Click button2 to generate Effect 2
   button2.setOnClickListener {
     vibrator.vibrate(VibrationEffect.createOneShot(oneShotTiming, oneShotAmplitude))
   }

   // Click button3 to generate Effect 3
   button3.setOnClickListener {
     vibrator.vibrate(
       VibrationEffect.createWaveform(waveformTimings, waveformAmplitudes, -1))

     // See quick results of Effect 3
     if (vibrator.hasAmplitudeControl()) {
       button3.text = "Effect 3: PASS"
       button3.setBackgroundColor(Color.GREEN)
       button3.setTextColor(Color.BLACK)
     } else {
       button3.text = "Effect 3: FAIL"
       button3.setBackgroundColor(Color.RED)
       button3.setTextColor(Color.WHITE)
     }
   }
 }
}

رمز مصدر التنسيق (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
   tools:context=".MainActivity">

   <Button
       android:id="@+id/button1"
       android:layout_width="350dp"
       android:layout_height="60dp"
       android:layout_marginStart="32dp"
       android:layout_marginTop="5dp"
       android:layout_marginEnd="32dp"
       android:text="Effect 1"
       android:textSize="18sp"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

   <Button
       android:id="@+id/button2"
       android:layout_width="350dp"
       android:layout_height="60dp"
       android:layout_marginStart="32dp"
       android:layout_marginTop="5dp"
       android:layout_marginEnd="32dp"
       android:text="Effect 2"
       android:textSize="18sp"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/button1" />

   <Button
       android:id="@+id/button3"
       android:layout_width="350dp"
       android:layout_height="60dp"
       android:layout_marginStart="32dp"
       android:layout_marginTop="5dp"
       android:layout_marginEnd="32dp"
       android:text="Effect 3"
       android:textSize="18sp"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/button2" />

   <View
       android:id="@+id/divider"
       android:layout_width="363dp"
       android:layout_height="1dp"
       android:layout_marginStart="32dp"
       android:layout_marginTop="10dp"
       android:layout_marginEnd="32dp"
       android:background="?android:attr/listDivider"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintHorizontal_bias="0.5"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/button3" />

   <androidx.constraintlayout.widget.ConstraintLayout
       android:layout_width="363dp"
       android:layout_height="0dp"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintHorizontal_bias="0.5"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/divider">

       <ImageView
           android:id="@+id/imageView"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:adjustViewBounds="true"
           android:scaleType="fitXY"
           app:layout_constraintBottom_toBottomOf="parent"
           app:layout_constraintEnd_toEndOf="parent"
           app:layout_constraintHorizontal_bias="0.5"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toTopOf="parent"
           app:srcCompat="@drawable/bluebar" />
   </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

مقياس التسارع

الشكل 3. إرفاق مقياس التسارع على طول المنطقة المقترَحة في واجهة المستخدم