1
1

More than 1 year has passed since last update.

Android java GoogleMAP API を使用した、アプリ制作(ゴミ処理業者 検索アプリ)

Posted at

■ UI

・郵便番号を入力
夏目 智徹 android map app 01


・入力された郵便番号の【5km】圏内で、CSVファイルで取得した業者の経度・緯度を計算して表示する。
夏目智徹 android map app 02

・入力された郵便番号の【10km】圏内で、CSVファイルで取得した業者の経度・緯度を計算して表示する。
夏目 智徹 android map app 03


・リストをタップしたら、マップ画面表示
夏目 智徹 android map app 03

■ソースコード

java MainActivity.java
package com.example.map_kensaku_app_01;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.gms.maps.model.LatLng;

import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.renderscript.ScriptGroup;
import android.text.InputType;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;

public class MainActivity extends AppCompatActivity {

    private EditText editTextPostalCode;
    private Button buttonSearch;
    private ListView listViewLocations;
    private LocationAdapter locationAdapter;

    private List<LocationData> locationDataList;

    private List<LocationData> items;
    private int kensaku_i;
    private RadioButton RadioButtonB2;
    private ImageButton ImageButton;

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

        editTextPostalCode = findViewById(R.id.editTextPostalCode);
        buttonSearch = findViewById(R.id.buttonSearch);
        listViewLocations = findViewById(R.id.listViewLocations);


        locationAdapter = new LocationAdapter(this);
        listViewLocations.setAdapter(locationAdapter);

        // === エディットテキスト 数字入力設定
        editTextPostalCode.setInputType(InputType.TYPE_CLASS_NUMBER);

        /**
         *    // CSVファイルからデータを読み込む
         */
        locationDataList = loadLocationData();

        buttonSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // === 住所(入力された住所を取得)
                String postalCode = editTextPostalCode.getText().toString().trim();
                System.out.println("onclick ::: postalCode ::: 値 :::" + postalCode);

                if (!TextUtils.isEmpty(postalCode)) {
                    new GeocodeAsyncTask().execute(postalCode);
                } else {
                    Toast.makeText(MainActivity.this, "郵便番号を入力してください", Toast.LENGTH_SHORT).show();
                }
            }
        });


        /**
         *  リストビュー
         */
        listViewLocations.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                // クリックした位置の情報を取得する
                LocationData clickedLocation = (LocationData) locationAdapter.getItem(position);

                Double ido = clickedLocation.getLatitude(); // 緯度
                Double keido = clickedLocation.getLongitude(); // 経度取得

                // === マップへ飛ばす
                openMapActivity(ido, keido);

               //Toast.makeText(MainActivity.this, "クリックOK" + clickedLocation.getFacilityName(), Toast.LENGTH_SHORT).show();

            }
        });



        /**
         *  ========= ラジオボタン (検索範囲を、何キロにするかをきめる デフォルト 3km) =========
         */

        RadioGroup radioGroup = (RadioGroup) findViewById(R.id.RadioGroupB);
        RadioButton radioButton2 = (RadioButton) findViewById(R.id.RadioButtonB2);

        // === 初期値 取得
        RadioButtonB2 = findViewById(R.id.RadioButtonB2);
        String tmp_radio = (String) RadioButtonB2.getText();
        kensaku_i = Str_replace_int(tmp_radio, "km");

        // ラジオグループのチェック状態が変更された時に呼び出されるコールバックリスナーを登録します
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                RadioButton radioButton = (RadioButton) findViewById(checkedId);

                String tmp_radio = (String) radioButton.getText();
                kensaku_i = Str_replace_int(tmp_radio, "km");

            }
        });

        // 指定した ID のラジオボタンをチェックします
        radioButton2.setChecked(true);

    }

    private List<LocationData> loadLocationData() {
        List<LocationData> dataList = new ArrayList<>();

        try {
            InputStream inputStream = getResources().openRawResource(R.raw.location_data);
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            Integer count = 1;
            while ((line = reader.readLine()) != null) {
                String[] data = line.split(",");
                if (data.length >= 3) {
                    String facilityName = data[0];
                    String zyuusyo = data[1];
                    double latitude = Double.parseDouble(data[2]); // 緯度
                    double longitude = Double.parseDouble(data[3]); // 経度

                    System.out.println("loadLocationData => facilityName:::" + count + "行データ:::" + facilityName + ":::latitude:::" +
                            latitude + ":::latitude:::" + latitude);

                    // === 行数カウント
                    count++;

                    LocationData locationData = new LocationData(facilityName, latitude, longitude, zyuusyo);
                    dataList.add(locationData);
                }
            }

            reader.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return dataList;
    }

    private class GeocodeAsyncTask extends AsyncTask<String, Void, LatLng> {

        @Override
        protected LatLng doInBackground(String... params) {
            String postalCode = params[0];
            double latitude = 0.0, longitude = 0.0;

            System.out.println("doInBackground ::: postalCode 値 :::" + postalCode);

            // === 郵便番号を座標へ変換
            LatLng location = getLocationFromAddress(postalCode);
            System.out.println("doInBackgroundlocation ::: 値 :::" + location);

            String location_tmp = location.toString();
            String start = "(";
            String end = ",";

            String start_02 = ",";
            String end_02 = ")";

            String location_lat = Substring(location_tmp, start, end);
            String location_lon = Substring(location_tmp, start_02, end_02);

            double location_lat_d = Double.parseDouble(location_lat);
            double location_lon_d = Double.parseDouble(location_lon);

            latitude = location_lat_d;  // 緯度
            longitude = location_lon_d; // 経度


            return new LatLng(latitude, longitude);
        }

        @Override
        protected void onPostExecute(LatLng latLng) {
            if (latLng == null) {
                Toast.makeText(MainActivity.this, "該当する場所が見つかりませんでした", Toast.LENGTH_SHORT).show();
            } else {
                List<LocationData> filteredList = new ArrayList<>();

                Location location1 = new Location("");
                location1.setLatitude(latLng.latitude);
                location1.setLongitude(latLng.longitude);

                System.out.println("onPostExecute ::: ********* location1 ********* latLng.latitude:::値:::" + latLng.latitude);
                System.out.println("onPostExecute ::: ********* location1 ********* latLng.longitude:::値:::" + latLng.longitude);

                for (LocationData data : locationDataList) {
                    Location location2 = new Location("");
                    location2.setLatitude(data.getLatitude());
                    location2.setLongitude(data.getLongitude());

                    System.out.println("onPostExecute :::location2 data.getLatitude:::値:::" + data.getLatitude());
                    System.out.println("onPostExecute :::location2 data.getLongitude:::値:::" + data.getLongitude());

                    System.out.println("onPostExecute ::: ********* location2 ********* :::値:::" + location2);

                    float distance = location1.distanceTo(location2) / 1000; // メートルをキロメートルに変換

                    System.out.println("onPostExecute distance 値:::" + distance);

                    /**
                     *   kensaku_i => デフォルト値 3キロ
                     *   === distance <= 3    3キロ以内
                     */
                    if (distance <= kensaku_i) {
                        filteredList.add(data);
                    }
                }

                if (filteredList.isEmpty()) {
                    Toast.makeText(MainActivity.this, "半径3km以内の施設が見つかりませんでした", Toast.LENGTH_SHORT).show();
                } else {
                    locationAdapter.setLocationDataList(filteredList);
                    locationAdapter.notifyDataSetChanged();
                }
            }
        }
    }

    /**
     *   住所から座標を取得
     */
    private LatLng getLocationFromAddress(String strAddress) {
        Geocoder coder = new Geocoder(this);
        List<Address> addressList;
        LatLng location = null;

        try {
            addressList = coder.getFromLocationName(strAddress, 1);
            if (addressList != null && !addressList.isEmpty()) {
                Address address = addressList.get(0);
                double latitude = address.getLatitude();
                double longitude = address.getLongitude();
                location = new LatLng(latitude, longitude);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return location;
    }

    /**
     *    開始文字と、終了文字を指定して、その間の文字列を取得
     *
     */
    public static String Substring(String all_str, String start, String end) {

        int startIndex = all_str.indexOf(start);
        System.out.println("startIndex:::" + startIndex); // 5

        int endIndex = all_str.indexOf(end, startIndex + start.length());

        System.out.println("endIndex:::" + endIndex); // 12
        System.out.println("start.length():::" + start.length()); // 1

        return all_str.substring(startIndex + start.length(), endIndex);

    }

    private void openMapActivity(double latitude, double longitude) {
        Intent intent = new Intent(MainActivity.this, MapActivity.class);
        intent.putExtra("latitude", latitude);
        intent.putExtra("longitude", longitude);
        startActivity(intent);
    }

    /**
     *  文字列を空白に置換して、integer型に変換する。
     */
    public int Str_replace_int(String str, String cut) {

        String result_str = str.replace(cut, "");

        int result_num = Integer.parseInt(result_str);
        return result_num;

    }


}

```java LocationAdapter.java

package com.example.map_kensaku_app_01;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

/**
 *  リストビュー 用 アダプター
 */
public class LocationAdapter extends BaseAdapter {

    private Context context;
    private List<LocationData> locationDataList;

    public LocationAdapter(Context context) {
        this.context = context;
        this.locationDataList = new ArrayList<>();
    }

    public void setLocationDataList(List<LocationData> locationDataList) {
        this.locationDataList = locationDataList;
    }

    @Override
    public int getCount(){
        return locationDataList.size();
    }

    @Override
    public Object getItem(int position) {
        return locationDataList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder;

        if(convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item_location, parent, false);

            viewHolder = new ViewHolder();
            viewHolder.textViewName = convertView.findViewById(R.id.textViewName);
            viewHolder.textViewLatitude = convertView.findViewById(R.id.textViewLatitude);
            viewHolder.textViewLongitude = convertView.findViewById(R.id.textViewLongitude);
            viewHolder.textView_addres = convertView.findViewById(R.id.textView_addres);

            // 地図アイコン ボタン
            viewHolder.list_image_icon = convertView.findViewById(R.id.list_image_icon);

            convertView.setTag(viewHolder);

        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        LocationData locationData = locationDataList.get(position);

        // === 値をセット
        viewHolder.textViewName.setText(locationData.getFacilityName());
        viewHolder.textViewLatitude.setText("●緯度:" + String.valueOf(locationData.getLatitude()));
        viewHolder.textViewLongitude.setText("●経度:" + String.valueOf(locationData.getLongitude()));

        viewHolder.textView_addres.setText(locationData.getZyuusyo()); // === 住所

        viewHolder.list_image_icon.setText("");

        return convertView;
    }

    private static class ViewHolder {
        TextView textViewName;
        TextView textViewLatitude;
        TextView textViewLongitude;
        TextView textView_addres; // 住所

        TextView list_image_icon;
    }



}

xml activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:background="#F9F4F5"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".MainActivity">


    <androidx.cardview.widget.CardView
        android:id="@+id/card_view_01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        card_view:cardElevation="8dp"
        card_view:cardCornerRadius="4dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        >

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="3dp"
            >


            <!--  何キロか範囲を指定するラジオボタン -->
            <RadioGroup
                android:id="@+id/RadioGroupB"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:layout_marginLeft="16dp"
                android:layout_marginRight="16dp"
                android:orientation="horizontal"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                >
                <RadioButton
                    android:text="3km"
                    android:id="@+id/RadioButtonB1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@drawable/btn_radio_left"
                    android:textColor="@drawable/btn_radio_textcolor"
                    android:layout_weight="1"
                    android:button="@null"
                    android:gravity="center">
                </RadioButton>
                <RadioButton
                    android:text="5km"
                    android:id="@+id/RadioButtonB2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@drawable/btn_radio_center"
                    android:textColor="@drawable/btn_radio_textcolor"
                    android:layout_weight="1"
                    android:button="@null"
                    android:gravity="center">
                </RadioButton>
                <RadioButton
                    android:text="10km"
                    android:id="@+id/RadioButtonB3"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@drawable/btn_radio_center"
                    android:textColor="@drawable/btn_radio_textcolor"
                    android:layout_weight="1"
                    android:button="@null"
                    android:gravity="center">
                </RadioButton>
                <RadioButton
                    android:text="100km"
                    android:id="@+id/RadioButtonB4"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@drawable/btn_radio_right"
                    android:textColor="@drawable/btn_radio_textcolor"
                    android:layout_weight="1"
                    android:button="@null"
                    android:gravity="center">
                </RadioButton>
            </RadioGroup>


            <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/editTextPostalCode_box"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/RadioGroupB"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginTop="35dp"
        app:errorEnabled="true"
        app:counterEnabled="true"
        app:counterMaxLength="7"
        app:hintEnabled="true"
        app:hintAnimationEnabled="true"
        android:paddingHorizontal="30dp"
        app:boxStrokeColor="#ffffff"
        >

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/editTextPostalCode"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="郵便番号を入力してください。(-ハイフンは無し)"
            android:imeOptions="actionDone"
            android:inputType="textEmailAddress"
            android:maxLength="7"
            android:maxLines="1"
            android:textSize="15sp"
            android:letterSpacing="0.2"
            />

    </com.google.android.material.textfield.TextInputLayout>



    <com.google.android.material.button.MaterialButton
        android:id="@+id/buttonSearch"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_gravity="bottom"
        android:text="検索"
        android:textAppearance="@style/TextAppearance.MaterialComponents.Button"
        app:backgroundTint="#2979ff"
        app:cornerRadius="9dp"
        android:layout_marginHorizontal="52dp"
        android:layout_marginTop="25dp"
        android:textSize="15.5dp"
        android:letterSpacing="0.2"
        app:layout_constraintTop_toBottomOf="@+id/editTextPostalCode_box"
        app:layout_constraintLeft_toLeftOf="parent"
        />



        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.cardview.widget.CardView>

    <ListView
        android:id="@+id/listViewLocations"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="295dp"
        app:layout_constraintTop_toBottomOf="@+id/card_view_01"
        app:layout_constraintLeft_toLeftOf="parent"
        />

</androidx.constraintlayout.widget.ConstraintLayout>


xml activity_map.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MapActivity">

    <fragment
        android:id="@+id/map_fragment"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>


1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1