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

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

  • 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 كيلوهرتز من خلال اختيار 48000 في قائمة معدّل المشروع.

    معدّل أخذ العيّنات

    الشكل 2. ضبط معدّل البيانات في الملف الصوتي

تنزيل MATLAB

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

  2. استخرِج الملف وابحث عن Effect1NEffect2_V1p0_2020PM.m (للمؤثر 1 والمؤثر 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. تثبيت مقياس التسارع على طول المنطقة الموصى بها في واجهة المستخدم الرسومية