取得した位置情報をwp_locテーブルへ保存する

Kotlin

AndroidStudioのエミュレーター越しでもMySQLデータベースに保存することが出来ます。

functions.php

// カスタムエンドポイントの作成
add_action('rest_api_init', function() {
    register_rest_route('custom/v1', '/save_location/', array(
        'methods' => 'POST',
        'callback' => 'save_location_to_db',
        'permission_callback' => '__return_true',
    ));
});

// wp_locテーブルに保存する関数
function save_location_to_db(WP_REST_Request $request) {
    global $wpdb;

    $latitude = $request->get_param('latitude');
    $longitude = $request->get_param('longitude');
    $device_id = $request->get_param('device_id');

    if (!$latitude || !$longitude || !$device_id) {
        return new WP_Error('missing_data', '緯度、経度、デバイスIDが必要です', array('status' => 400));
    }

    $table_name = $wpdb->prefix . 'loc';
    $wpdb->insert($table_name, array(
        'device_id' => sanitize_text_field($device_id),
        'latitude' => sanitize_text_field($latitude),
        'longitude' => sanitize_text_field($longitude),
        'created_at' => current_time('mysql')
    ));

    return rest_ensure_response(array('status' => 'success', 'message' => '位置情報を保存しました'));
}

AndroidManifest.xml

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/> ※1
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> ※1

※1 … インターネット(WordPressサイト)にアクセスするのでパーミッションが必要です。

build.gradle.kt (Module: app)

dependencies {
    implementation("com.android.volley:volley:1.2.1") ※2
    implementation("com.google.android.gms:play-services-location:21.0.1")
}

※2 … 非同期通信にvolleyを使います。(RetrofitでもOK)

REST APIの制限解除

ConohaWingのコントロールパネルで「海外アクセス制限」のREST-APIをOFFにします。

MainActivity.kt

package com.example.application0210

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat

import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.location.Location
import android.util.Log
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.*
import com.google.android.gms.location.FusedLocationProviderClient

import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import org.json.JSONObject
import java.util.*


class MainActivity : AppCompatActivity() {

    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var locationCallback: LocationCallback
    private lateinit var locationRequest: LocationRequest
    private lateinit var textLocation: TextView
    private lateinit var requestQueue: RequestQueue
    private val serverUrl = "https://sample.com/wp-json/custom/v1/save_location/"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }

        //
        textLocation = findViewById(R.id.textLocation)

        //
        requestQueue = Volley.newRequestQueue(this)

        // 位置情報のクライアントを取得
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        // 位置情報のリクエスト設定
        locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 5000).build()

        // 位置情報の更新を受け取るコールバック
        locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                for (location in locationResult.locations) {
                    updateLocationUI(location)
                    sendLocationToServer(location)
                }
            }
        }

        // 権限をリクエスト
        requestLocationPermissions()
    }

    private fun requestLocationPermissions() {
        val requestPermissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestMultiplePermissions()
        ) { permissions ->
            if (permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true ||
                permissions[Manifest.permission.ACCESS_COARSE_LOCATION] == true) {
                startLocationUpdates()
            } else {
                textLocation.text = "権限がありません"
            }
        }

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            requestPermissionLauncher.launch(
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION)
            )
        } else {
            startLocationUpdates()
        }
    }

    @SuppressLint("MissingPermission")
    private fun startLocationUpdates() {
        fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
    }

    private fun stopLocationUpdates() {
        fusedLocationClient.removeLocationUpdates(locationCallback)
    }

    private fun updateLocationUI(location: Location) {
        val locationText = "緯度: ${location.latitude}, 経度: ${location.longitude}"
        textLocation.text = locationText
    }


    private fun sendLocationToServer(location: Location) {
        val params = HashMap<String, String>()
        params["device_id"] = UUID.randomUUID().toString()
        params["latitude"] = location.latitude.toString()
        params["longitude"] = location.longitude.toString()

        val request = object : StringRequest(
            Request.Method.POST, serverUrl,
            Response.Listener { response ->
                Log.d("ServerResponse", "成功: $response")
            },
            Response.ErrorListener { error ->
                Log.e("ServerError", "エラー: ${error.message}")
            }
        ) {
            override fun getParams(): MutableMap<String, String> {
                return params
            }
        }

        requestQueue.add(request)
    }

    override fun onDestroy() {
        super.onDestroy()
        stopLocationUpdates()
    }
}

エラー: java.io.IOException: Cleartext HTTP traffic to azurlane.work not permitted

HTTP通信がブロックされています。

private val serverUrl = "http://sample.com/wp-json/custom/v1/save_location"

を「http」から「https」にしてください。

BACK