[JAVA] Android-based control and UDP communication application using accelerometer values

Changes from the last time

Until the last time, the acceleration sensor was controlled by displaying an image imitating an LED, but this time it has been changed so that the acceleration sensor can be controlled using radio buttons and spinners.

Application GUI

In this application, the values of the three axes (X, Y, Z) accelerometers are sent by UDP communication. Control using an acceleration sensor in the terminal can now be performed using radio buttons and spinners. Since the control items are set with the radio buttons, you can control only one axis at a time.

Application GUI

For ASUS Tab K013

Source code

Since socket communication is performed, add the following to Androidmanifest.xml.

Androidmanifest.xml


<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Next, in order to handle image and audio files, create drawable and raw of res in the app, and put the image data and audio data in it. After that, since a spinner is used, Spinner.xml is created in values in res.

app
 └res
   ├drawable
   │ ├en.jpg
   │ ├en_gleen.jpg
   │ └en_red.jpg
   ├raw
   │ ├xjikum.mp3
   │ ├xjikup.mp3
   │ ├yjikum.mp3
   │ ├yjikup.mp3
   │ ├zjikum.mp3
   │ └zjikup.mp3
   └values
     └Spinner.xml

The source code of Spinner.xml is as follows

Spinner.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="items">
        <item>that's all</item>
        <item>Less than</item>
    </string-array>
</resources>

activity_main.xml


<Spinner
        android:id="@+id/spinner2"
        android:layout_width="67dp"
        android:layout_height="32dp"
        android:layout_marginStart="8dp"
        android:layout_marginBottom="180dp"
        android:entries="@array/items"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/y_if" />

    <Spinner
        android:id="@+id/spinner3"
        android:layout_width="67dp"
        android:layout_height="32dp"
        android:layout_marginStart="8dp"
        android:layout_marginBottom="128dp"
        android:entries="@array/items"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/z_if" />

    <EditText
        android:id="@+id/IP_Address"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="52dp"
        android:layout_marginEnd="16dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="127.0.0.1"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/Port"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="48dp"
        android:layout_marginEnd="16dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="8080"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/IP_Address" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="280dp"
        android:text="X:"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="24dp"
        android:text="Y:"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="24dp"
        android:text="Z:"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2" />

    <TextView
        android:id="@+id/X_Data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="280dp"
        android:text="TextView"
        android:textSize="24sp"
        app:layout_constraintStart_toEndOf="@+id/textView"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/Y_Data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="TextView"
        android:textSize="24sp"
        app:layout_constraintStart_toEndOf="@+id/textView2"
        app:layout_constraintTop_toBottomOf="@+id/X_Data" />

    <TextView
        android:id="@+id/Z_Data"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="TextView"
        android:textSize="24sp"
        app:layout_constraintStart_toEndOf="@+id/textView3"
        app:layout_constraintTop_toBottomOf="@+id/Y_Data" />

    <TextView
        android:id="@+id/textView7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="230dp"
        android:text="Accelerometer value"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/Ran"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="87dp"
        android:layout_marginLeft="87dp"
        android:layout_marginBottom="70dp"
        android:text="Start communication"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginBottom="8dp"
        android:text="IP address"
        android:textSize="24sp"
        app:layout_constraintBottom_toTopOf="@+id/IP_Address"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginBottom="8dp"
        android:text="port number"
        android:textSize="24sp"
        app:layout_constraintBottom_toTopOf="@+id/Port"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/End"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="87dp"
        android:layout_marginRight="87dp"
        android:layout_marginBottom="70dp"
        android:text="Communication cancellation"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <TextView
        android:id="@+id/textView6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="300dp"
        android:layout_marginEnd="124dp"
        android:text="Delay"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/Delay"
        android:layout_width="159dp"
        android:layout_height="49dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="40dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="100"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView6" />

    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="67dp"
        android:layout_height="32dp"
        android:layout_marginStart="8dp"
        android:layout_marginBottom="248dp"
        android:entries="@array/items"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/x_if" />

    <EditText
        android:id="@+id/y_if"
        android:layout_width="66dp"
        android:layout_height="49dp"
        android:layout_marginStart="8dp"
        android:layout_marginBottom="183dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="500"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/RBGroup" />

    <EditText
        android:id="@+id/x_if"
        android:layout_width="66dp"
        android:layout_height="49dp"
        android:layout_marginStart="8dp"
        android:layout_marginBottom="243dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="500"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/RBGroup" />

    <EditText
        android:id="@+id/z_if"
        android:layout_width="66dp"
        android:layout_height="49dp"
        android:layout_marginStart="8dp"
        android:layout_marginBottom="123dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="500"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/RBGroup" />


    <RadioGroup
        android:id="@+id/RBGroup"
        android:layout_width="125dp"
        android:layout_height="180dp"
        android:layout_marginStart="40dp"
        android:layout_marginBottom="113dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent">


        <RadioButton
            android:id="@+id/x_button"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="The value of X is"
            android:textSize="24sp" />

        <RadioButton
            android:id="@+id/y_button"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="The value of Y is"
            android:textSize="24sp" />

        <RadioButton
            android:id="@+id/z_button"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="The value of Z is"
            android:textSize="24sp" />
    </RadioGroup>

MainActivity.java


import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private SensorManager sensorManager;
    private TextView X_Data_TextView,Y_Data_TextView,Z_Data_TextView;
    private float data_X,data_Y,data_Z;
    private int data_x,data_y,data_z;
    private String Data;
    private Timer timer1,timer2;
    private mTimerTask1 timerTask1;
    private mTimerTask2 timerTask2;
    private Handler handler = new Handler();
    private long Delay;
    private Spinner spinner1,spinner2,spinner3;
    private int spn1,spn2,spn3;
    private int X,Y,Z;
    private String x,y,z;
    SoundPool soundPool;
    int mp3_xp,mp3_xm,mp3_yp,mp3_ym,mp3_zp,mp3_zm;
    private int xp,yp,zp,xm,ym,zm;
    private RadioGroup rg ;
    private RadioButton RBid;

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

        //Accelerometer settings
        sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);

        //Setting the text to display the acceleration
        X_Data_TextView = findViewById(R.id.X_Data);
        Y_Data_TextView = findViewById(R.id.Y_Data);
        Z_Data_TextView = findViewById(R.id.Z_Data);

        //The one you need to add sound effects
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
        } else {
            AudioAttributes attr = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_MEDIA)
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    .build();
            soundPool = new SoundPool.Builder()
                    .setAudioAttributes(attr)
                    .setMaxStreams(5)
                    .build();
        }

        //Sound effect setting
        mp3_xp = soundPool.load(this, R.raw.xjikup, 1);
        mp3_xm = soundPool.load(this,R.raw.xjikum,1 );
        mp3_yp = soundPool.load(this, R.raw.yjikup, 1);
        mp3_ym = soundPool.load(this,R.raw.yjikum,1 );
        mp3_zp = soundPool.load(this, R.raw.zjikup, 1);
        mp3_zm = soundPool.load(this,R.raw.zjikum,1 );

        //Spinner settings
        spinner1=findViewById(R.id.spinner1);
        spinner2=findViewById(R.id.spinner2);
        spinner3=findViewById(R.id.spinner3);

        //Radio button group settings and value acquisition
        rg =findViewById(R.id.RBGroup);
        rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                RBid = findViewById(checkedId);
            }
        });

        //Setting start and disconnect buttons
        Button ran = findViewById(R.id.Ran);
        Button end = findViewById(R.id.End);

        //Processing when the connection start button is pressed
        ran.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(null != timer1){
                    timer1.cancel();
                    timer1 = null;
                }

                xp=yp=zp=xm=ym=zm=0;

                //Delay setting
                String delay = ((EditText)findViewById(R.id.Delay)).getText().toString();
                Delay = Long.parseLong(delay);

                //UDP communication started
                timer1 = new Timer();
                timerTask1 = new mTimerTask1();
                timer1.schedule(timerTask1,0, Delay);

                //Control using an accelerometer
                timer2 = new Timer();
                timerTask2 = new mTimerTask2();
                timer2.schedule(timerTask2,0,Delay);
            }
        });

        end.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if(null != timer1){
                    timer1.cancel();
                    timer1 = null;
                }

                //IP address and port number settings
                final String address = ((EditText) findViewById(R.id.IP_Address)).getText().toString();
                String port = ((EditText) findViewById(R.id.Port)).getText().toString();
                int Port = Integer.parseInt(port);

                //Settings for sending "exit"
                String exit = "exit";
                byte buf[] = new byte[exit.length()];
                try {
                    buf = exit.getBytes("SHIFT_JIS");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                //Start UDP communication
                InetSocketAddress inetSocketAddress = new InetSocketAddress(address, Port);
                final DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length, inetSocketAddress);
                AsyncTask<DatagramPacket, Void, Void> task = new AsyncTask<DatagramPacket, Void, Void>() {
                    @Override
                    protected Void doInBackground(DatagramPacket... datagramPackets) {
                        DatagramSocket datagramSocket = null;
                        try {
                            datagramSocket = new DatagramSocket();
                            datagramSocket.send(datagramPackets[0]);
                            datagramSocket.close();
                        } catch (SocketException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        return null;
                    }

                };
                task.execute(datagramPacket);

            }
        });

    }



    @Override
    protected void onResume(){
        super.onResume();
        //Event Listener registration
        Sensor accel = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sensorManager.registerListener((SensorEventListener) this,accel,SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause(){
        super.onPause();
        //Event Listener unregistered
        sensorManager.unregisterListener((SensorEventListener) this);
    }

    //Settings for displaying the value of the accelerometer and transmitting via UDP communication
    @Override
    public void onSensorChanged(SensorEvent event){
        if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){

            data_X= (500+event.values[0]*25);
            data_Y= (500+event.values[1]*25);
            data_Z= (500+event.values[2]*25);

            data_x = (int)data_X;
            data_y = (int)data_Y;
            data_z = (int)data_Z;
            Data = data_x + " " +
                    data_y + " " +
                    data_z;
            X_Data_TextView.setText(String.valueOf(data_x));
            Y_Data_TextView.setText(String.valueOf(data_y));
            Z_Data_TextView.setText(String.valueOf(data_z));
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy){

    }

    //Control using the value of the accelerometer
    private class mTimerTask2 extends TimerTask{
        @Override
        public void run() {
            handler.post(new Runnable() {
                @Override
                public void run() {

                    spn1=spinner1.getSelectedItemPosition();
                    spn2=spinner2.getSelectedItemPosition();
                    spn3=spinner3.getSelectedItemPosition();

                    x=((EditText)findViewById(R.id.x_if)).getText().toString();
                    y=((EditText)findViewById(R.id.y_if)).getText().toString();
                    z=((EditText)findViewById(R.id.z_if)).getText().toString();
                    X=Integer.parseInt(x);
                    Y=Integer.parseInt(y);
                    Z=Integer.parseInt(z);

                    if(RBid==(findViewById(R.id.x_button))&&spn1==0&&data_x>=X){
                        xp += 1;
                        if (xp == 1) {
                            yp=zp=xm=ym=zm=0;
                            soundPool.play(mp3_xp, 2, 2, 0, 0, 1f);
                        }
                    }
                    else if(RBid==(findViewById(R.id.x_button))&&spn1==1&&data_x<=X){
                        xm += 1;
                        if (xm == 1) {
                            xp=yp=zp=ym=zm=0;
                            soundPool.play(mp3_xm, 2, 2, 0, 0, 1f);
                        }
                    }
                    else if(RBid==(findViewById(R.id.y_button))&&spn2==0&&data_y>=Y){
                        yp += 1;
                        if (yp == 1) {
                            xp=zp=xm=ym=zm=0;
                            soundPool.play(mp3_yp, 2, 2, 0, 0, 1f);
                        }
                    }
                    else if(RBid==(findViewById(R.id.y_button))&&spn2==1&&data_y<=Y){
                        ym += 1;
                        if (ym == 1) {
                            xp=yp=zp=xm=zm=0;
                            soundPool.play(mp3_ym, 2, 2, 0, 0, 1f);
                        }
                    }
                    else if(RBid==(findViewById(R.id.z_button))&&spn3==0&&data_z>=Z){
                        zp += 1;
                        if (zp == 1) {
                            xp=yp=xm=ym=zm=0;
                            soundPool.play(mp3_zp, 2, 2, 0, 0, 1f);
                        }
                    }
                    else if(RBid==(findViewById(R.id.z_button))&&spn3==1&&data_z<=Z){
                        zm += 1;
                        if (zm == 1) {
                            xp=yp=zp=xm=ym=0;
                            soundPool.play(mp3_zm, 2, 2, 0, 0, 1f);
                        }
                    }
                    else{
                        xp=xm=yp=ym=zp=zm=0;
                    }
                }
            });
        }

    }

    //UDP communication
    private class mTimerTask1 extends TimerTask{
        @Override
        public void run(){

            handler.post(new Runnable() {
                @Override
                public void run() {
                    final String address = ((EditText) findViewById(R.id.IP_Address)).getText().toString();
                    String port = ((EditText) findViewById(R.id.Port)).getText().toString();
                    int Port = Integer.parseInt(port);
                    byte buf[] = new byte[Data.length()];

                    try {
                        buf = Data.getBytes("SHIFT_JIS");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }

                    InetSocketAddress inetSocketAddress = new InetSocketAddress(address, Port);
                    final DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length, inetSocketAddress);


                    AsyncTask<DatagramPacket, Void, Void> task = new AsyncTask<DatagramPacket, Void, Void>() {
                        @Override
                        protected Void doInBackground(DatagramPacket... datagramPackets) {
                            DatagramSocket datagramSocket = null;

                            try {
                                datagramSocket = new DatagramSocket();
                                datagramSocket.send(datagramPackets[0]);
                                datagramSocket.close();
                            } catch (SocketException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }

                            return null;
                        }

                    };
                    task.execute(datagramPacket);
                }
            });

        }
    }
}

Recommended Posts

Android-based control and UDP communication application using accelerometer values
An application that acquires the value of the accelerometer by UDP communication between C # and Android
Construction of authorization server using Authlete and communication from OAuth client (Web application)