محاسبه فاصله بین دو مختصات در نقشه با استفاده از API Google Maps
سلام دوستان .در این پست میخواهیم مسافت بین دو مختصات نقشه را محاسبه کنیم. همچنین مسیر بین مختصاتهای داده شده را ترسیم خواهیم کرد.
قبل از اینکه این پست را دنبال کنید باید یک مروری روی آموزش برنامه Google maps داشته باشید.
ایجاد پروژه اندروید
- اندروید استودیو را باز کرده ویک پروژه جدید ایجاد کنید. حالا باید اکتیویتی مپ (Activity Maps ) را انتخاب کنید.
- همچنین به یک کلید API نیاز داریدکه شما میتوانید از کنسول توسعه دهنده اندروید بگیرید . ما یک کلید API برای اندروید داریم . اما برای اپلیکیشن محاسبه مسافت گوگل به یک کلید API برای سرور نیاز داریم.
- به Google Maps Direction API بروید و روی GET A KEY کلیک کنید.
حالا پروژه خود را انتخاب کرده و روی ادامه کلیک کنید.
حالا به Credential جدید بروید و یک کلید سرور ایجاد کنید(فرض میکنیم که شما قبلا کلید اندروید را دارید)
کلید سرور خودتان را یادداشت کنید و به پروژه خود در اندروید استودیو باز گردید.
اضافه کردن Google Maps Android API و کتابخانه Volly
- در این برنامه باید فاصله بین دو مختصات از نقشه را محاسبه کنیم .
- باید یک درخواست Http برای گرفتن مسیر بین دو مختصات بفرستیم .
- برای اینکارها از کتابخانه Volly استفاده میکنیم
- پس به فایل gradle.build رفته و dependencies های زیر را اضافه میکنیم.
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.google.android.gms:play-services:8.3.0' compile 'com.google.maps.android:android-maps-utils:0.4+' compile 'com.mcxiaoke.volley:library-aar:1.0.0' }
حالا به activity_maps.xml بروید و کد زیر را بنویسید.
<FrameLayout 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=".MapsActivity"> <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:map="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="net.simplifiedcoding.mymapapp.MapsActivity" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#cc3b60a7" android:orientation="horizontal"> <Button android:id="@+id/buttonSetFrom" android:text="Set From" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/buttonSetTo" android:text="Set To" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/buttonCalcDistance" android:text="Calc Distance" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> </FrameLayout>
- همانطور که میبینید تنها سه دکمه روی لایوت داریم و یک فرگمنت (fragment) برای نمایش نقشه داریم .دکمه ها برای تنظیم مختصات و محاسبه مسافت هستند .زمانی که کاربر مسافت را محاسبه کرد ما مسیر بین دو مختصات را نشان خواهیم داد.
- پس به MapsActivity.java بروید و کد زیر را بنویسید:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, GoogleMap.OnMarkerDragListener, GoogleMap.OnMapLongClickListener, View.OnClickListener{ //Our Map private GoogleMap mMap; //To store longitude and latitude from map private double longitude; private double latitude; //From -> the first coordinate from where we need to calculate the distance private double fromLongitude; private double fromLatitude; //To -> the second coordinate to where we need to calculate the distance private double toLongitude; private double toLatitude; //Google ApiClient private GoogleApiClient googleApiClient; //Our buttons private Button buttonSetTo; private Button buttonSetFrom; private Button buttonCalcDistance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); // Obtain the SupportMapFragment and get notified when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); //Initializing googleapi client // ATTENTION: This "addApi(AppIndex.API)"was auto-generated to implement the App Indexing API. // See https://g.co/AppIndexing/AndroidStudio for more information. googleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .addApi(AppIndex.API).build(); buttonSetTo = (Button) findViewById(R.id.buttonSetTo); buttonSetFrom = (Button) findViewById(R.id.buttonSetFrom); buttonCalcDistance = (Button) findViewById(R.id.buttonCalcDistance); buttonSetTo.setOnClickListener(this); buttonSetFrom.setOnClickListener(this); buttonCalcDistance.setOnClickListener(this); } @Override protected void onStart() { googleApiClient.connect(); super.onStart(); // ATTENTION: This was auto-generated to implement the App Indexing API. // See https://g.co/AppIndexing/AndroidStudio for more information. Action viewAction = Action.newAction( Action.TYPE_VIEW, // TODO: choose an action type. "Maps Page", // TODO: Define a title for the content shown. // TODO: If you have web page content that matches this app activity's content, // make sure this auto-generated web page URL is correct. // Otherwise, set the URL to null. Uri.parse("http://host/path"), // TODO: Make sure this auto-generated app deep link URI is correct. Uri.parse("android-app://net.simplifiedcoding.googlemapsdistancecalc/http/host/path") ); AppIndex.AppIndexApi.start(googleApiClient, viewAction); } @Override protected void onStop() { googleApiClient.disconnect(); super.onStop(); // ATTENTION: This was auto-generated to implement the App Indexing API. // See https://g.co/AppIndexing/AndroidStudio for more information. Action viewAction = Action.newAction( Action.TYPE_VIEW, // TODO: choose an action type. "Maps Page", // TODO: Define a title for the content shown. // TODO: If you have web page content that matches this app activity's content, // make sure this auto-generated web page URL is correct. // Otherwise, set the URL to null. Uri.parse("http://host/path"), // TODO: Make sure this auto-generated app deep link URI is correct. Uri.parse("android-app://net.simplifiedcoding.googlemapsdistancecalc/http/host/path") ); AppIndex.AppIndexApi.end(googleApiClient, viewAction); } //Getting current location private void getCurrentLocation() { mMap.clear(); //Creating a location object Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); if (location != null) { //Getting longitude and latitude longitude = location.getLongitude(); latitude = location.getLatitude(); //moving the map to location moveMap(); } } //Function to move the map private void moveMap() { //Creating a LatLng Object to store Coordinates LatLng latLng = new LatLng(latitude, longitude); //Adding marker to map mMap.addMarker(new MarkerOptions() .position(latLng) //setting position .draggable(true) //Making the marker draggable .title("Current Location")); //Adding a title //Moving the camera mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); //Animating the camera mMap.animateCamera(CameraUpdateFactory.zoomTo(15)); } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; LatLng latLng = new LatLng(-34, 151); mMap.addMarker(new MarkerOptions().position(latLng).draggable(true)); mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); mMap.setOnMarkerDragListener(this); mMap.setOnMapLongClickListener(this); } @Override public void onConnected(Bundle bundle) { getCurrentLocation(); } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } @Override public void onMapLongClick(LatLng latLng) { //Clearing all the markers mMap.clear(); //Adding a new marker to the current pressed position mMap.addMarker(new MarkerOptions() .position(latLng) .draggable(true)); latitude = latLng.latitude; longitude = latLng.longitude; } @Override public void onMarkerDragStart(Marker marker) { } @Override public void onMarkerDrag(Marker marker) { } @Override public void onMarkerDragEnd(Marker marker) { //Getting the coordinates latitude = marker.getPosition().latitude; longitude = marker.getPosition().longitude; //Moving the map moveMap(); } @Override public void onClick(View v) { if(v == buttonSetFrom){ fromLatitude = latitude; fromLongitude = longitude; Toast.makeText(this,"From set",Toast.LENGTH_SHORT).show(); } if(v == buttonSetTo){ toLatitude = latitude; toLongitude = longitude; Toast.makeText(this,"To set",Toast.LENGTH_SHORT).show(); } if(v == buttonCalcDistance){ //This method will show the distance and will also draw the path calculateDistance(); } } }
- تا اینجا میتوانیم دو مختصات نقشه را بگیریم . آخرین کارهایی که برای این برنامه باید انجام دهیم این است:
۱- باید فاصله بین دو مختصات را محاسبه کنیم.
۲- باید یک مسیر بین دو مختصات بکشیم.
- با استفاده از Google Maps API Utility Library , محاسبه فاصله بسیار آسان است. میتوانیم از کد زیر برای محاسبه فاصله بین مختصاتها استفاده کنیم.
//Getting both the coordinates LatLng from = new LatLng(fromLatitude,fromLongitude); LatLng to = new LatLng(toLatitude,toLongitude); //Calculating the distance in meters Double distance = SphericalUtil.computeDistanceBetween(from, to); //Displaying the distance Toast.makeText(this,String.valueOf(distance+" Meters"),Toast.LENGTH_SHORT).show();
- برای ترسیم مسیر بین مختصاتها نیاز به دانستن مسیر داریم . اینکار کمی مشکل است چون ما نیاز داریم که API Google Maps Direction را صدا بزنیم.برای اینکار نشانی اینترنتی(URL) درخواستمانمان را ایجادخواهیم کرد. از کد زیر میتوانیم استفاده کنیم( SERVER-KEY رابا کلید سرور خودکه در اکانت توسعه دهنده گوگل (Google Developer’Account)ایجادکردید جایگزین کنید.)
public String makeURL (double sourcelat, double sourcelog, double destlat, double destlog ){ StringBuilder urlString = new StringBuilder(); urlString.append("https://maps.googleapis.com/maps/api/directions/json"); urlString.append("?origin=");// from urlString.append(Double.toString(sourcelat)); urlString.append(","); urlString .append(Double.toString( sourcelog)); urlString.append("&destination=");// to urlString .append(Double.toString( destlat)); urlString.append(","); urlString.append(Double.toString(destlog)); urlString.append("&sensor=false&mode=driving&alternatives=true"); urlString.append("&key=SERVER-KEY"); return urlString.toString(); }
متد بالا نشانی اینترنتی (URL)را به عنوان یک رشته به ما میدهد . ما باید یک درخواست نشانی اینترنتی (URL) بفرستیم و در برگشت JSON را دریافت خواهیم کرد.
- برای فرستادن درخواست ما از Volly استفاده میکنیم.
private void getDirection(){ //Getting the URL String url = makeURL(fromLatitude, fromLongitude, toLatitude, toLongitude); //Showing a dialog till we get the route final ProgressDialog loading = ProgressDialog.show(this, "Getting Route", "Please wait...", false, false); //Creating a string request StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() { @Override public void onResponse(String response) { loading.dismiss(); //Calling the method drawPath to draw the path drawPath(response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { loading.dismiss(); } }); //Adding the request to request queue RequestQueue requestQueue = Volley.newRequestQueue(this); requestQueue.add(stringRequest); }
این دو متد مسیر را روی نقشه ترسیم میکنند. ما اینرا از Stack Overflowگرفتیم.
//The parameter is the server response public void drawPath(String result) { //Getting both the coordinates LatLng from = new LatLng(fromLatitude,fromLongitude); LatLng to = new LatLng(toLatitude,toLongitude); //Calculating the distance in meters Double distance = SphericalUtil.computeDistanceBetween(from, to); //Displaying the distance Toast.makeText(this,String.valueOf(distance+" Meters"),Toast.LENGTH_SHORT).show(); try { //Parsing json final JSONObject json = new JSONObject(result); JSONArray routeArray = json.getJSONArray("routes"); JSONObject routes = routeArray.getJSONObject(0); JSONObject overviewPolylines = routes.getJSONObject("overview_polyline"); String encodedString = overviewPolylines.getString("points"); List<LatLng> list = decodePoly(encodedString); Polyline line = mMap.addPolyline(new PolylineOptions() .addAll(list) .width(20) .color(Color.RED) .geodesic(true) ); } catch (JSONException e) { } } private List<LatLng> decodePoly(String encoded) { List<LatLng> poly = new ArrayList<LatLng>(); int index = 0, len = encoded.length(); int lat = 0, lng = 0; while (index < len) { int b, shift = 0, result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lat += dlat; shift = 0; result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lng += dlng; LatLng p = new LatLng( (((double) lat / 1E5)), (((double) lng / 1E5) )); poly.add(p); } return poly; }
کد آخر از MapsActivity.java برای محاسبه مسافت خوهد بود.
package net.simplifiedcoding.googlemapsdistancecalc; import android.app.ProgressDialog; import android.graphics.Color; import android.location.Location; import android.net.Uri; import android.support.v4.app.FragmentActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.Volley; import com.google.android.gms.appindexing.Action; import com.google.android.gms.appindexing.AppIndex; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationServices; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import com.google.maps.android.SphericalUtil; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, GoogleMap.OnMarkerDragListener, GoogleMap.OnMapLongClickListener, View.OnClickListener{ //Our Map private GoogleMap mMap; //To store longitude and latitude from map private double longitude; private double latitude; //From -> the first coordinate from where we need to calculate the distance private double fromLongitude; private double fromLatitude; //To -> the second coordinate to where we need to calculate the distance private double toLongitude; private double toLatitude; //Google ApiClient private GoogleApiClient googleApiClient; //Our buttons private Button buttonSetTo; private Button buttonSetFrom; private Button buttonCalcDistance; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); // Obtain the SupportMapFragment and get notified when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); //Initializing googleapi client // ATTENTION: This "addApi(AppIndex.API)"was auto-generated to implement the App Indexing API. // See https://g.co/AppIndexing/AndroidStudio for more information. googleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .addApi(AppIndex.API).build(); buttonSetTo = (Button) findViewById(R.id.buttonSetTo); buttonSetFrom = (Button) findViewById(R.id.buttonSetFrom); buttonCalcDistance = (Button) findViewById(R.id.buttonCalcDistance); buttonSetTo.setOnClickListener(this); buttonSetFrom.setOnClickListener(this); buttonCalcDistance.setOnClickListener(this); } @Override protected void onStart() { googleApiClient.connect(); super.onStart(); // ATTENTION: This was auto-generated to implement the App Indexing API. // See https://g.co/AppIndexing/AndroidStudio for more information. Action viewAction = Action.newAction( Action.TYPE_VIEW, // TODO: choose an action type. "Maps Page", // TODO: Define a title for the content shown. // TODO: If you have web page content that matches this app activity's content, // make sure this auto-generated web page URL is correct. // Otherwise, set the URL to null. Uri.parse("http://host/path"), // TODO: Make sure this auto-generated app deep link URI is correct. Uri.parse("android-app://net.simplifiedcoding.googlemapsdistancecalc/http/host/path") ); AppIndex.AppIndexApi.start(googleApiClient, viewAction); } @Override protected void onStop() { googleApiClient.disconnect(); super.onStop(); // ATTENTION: This was auto-generated to implement the App Indexing API. // See https://g.co/AppIndexing/AndroidStudio for more information. Action viewAction = Action.newAction( Action.TYPE_VIEW, // TODO: choose an action type. "Maps Page", // TODO: Define a title for the content shown. // TODO: If you have web page content that matches this app activity's content, // make sure this auto-generated web page URL is correct. // Otherwise, set the URL to null. Uri.parse("http://host/path"), // TODO: Make sure this auto-generated app deep link URI is correct. Uri.parse("android-app://net.simplifiedcoding.googlemapsdistancecalc/http/host/path") ); AppIndex.AppIndexApi.end(googleApiClient, viewAction); } //Getting current location private void getCurrentLocation() { mMap.clear(); //Creating a location object Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); if (location != null) { //Getting longitude and latitude longitude = location.getLongitude(); latitude = location.getLatitude(); //moving the map to location moveMap(); } } //Function to move the map private void moveMap() { //Creating a LatLng Object to store Coordinates LatLng latLng = new LatLng(latitude, longitude); //Adding marker to map mMap.addMarker(new MarkerOptions() .position(latLng) //setting position .draggable(true) //Making the marker draggable .title("Current Location")); //Adding a title //Moving the camera mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); //Animating the camera mMap.animateCamera(CameraUpdateFactory.zoomTo(15)); } public String makeURL (double sourcelat, double sourcelog, double destlat, double destlog ){ StringBuilder urlString = new StringBuilder(); urlString.append("https://maps.googleapis.com/maps/api/directions/json"); urlString.append("?origin=");// from urlString.append(Double.toString(sourcelat)); urlString.append(","); urlString .append(Double.toString( sourcelog)); urlString.append("&destination=");// to urlString .append(Double.toString( destlat)); urlString.append(","); urlString.append(Double.toString(destlog)); urlString.append("&sensor=false&mode=driving&alternatives=true"); urlString.append("&key=SERVER-KEY"); return urlString.toString(); } private void getDirection(){ //Getting the URL String url = makeURL(fromLatitude, fromLongitude, toLatitude, toLongitude); //Showing a dialog till we get the route final ProgressDialog loading = ProgressDialog.show(this, "Getting Route", "Please wait...", false, false); //Creating a string request StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() { @Override public void onResponse(String response) { loading.dismiss(); //Calling the method drawPath to draw the path drawPath(response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { loading.dismiss(); } }); //Adding the request to request queue RequestQueue requestQueue = Volley.newRequestQueue(this); requestQueue.add(stringRequest); } //The parameter is the server response public void drawPath(String result) { //Getting both the coordinates LatLng from = new LatLng(fromLatitude,fromLongitude); LatLng to = new LatLng(toLatitude,toLongitude); //Calculating the distance in meters Double distance = SphericalUtil.computeDistanceBetween(from, to); //Displaying the distance Toast.makeText(this,String.valueOf(distance+" Meters"),Toast.LENGTH_SHORT).show(); try { //Parsing json final JSONObject json = new JSONObject(result); JSONArray routeArray = json.getJSONArray("routes"); JSONObject routes = routeArray.getJSONObject(0); JSONObject overviewPolylines = routes.getJSONObject("overview_polyline"); String encodedString = overviewPolylines.getString("points"); List<LatLng> list = decodePoly(encodedString); Polyline line = mMap.addPolyline(new PolylineOptions() .addAll(list) .width(20) .color(Color.RED) .geodesic(true) ); } catch (JSONException e) { } } private List<LatLng> decodePoly(String encoded) { List<LatLng> poly = new ArrayList<LatLng>(); int index = 0, len = encoded.length(); int lat = 0, lng = 0; while (index < len) { int b, shift = 0, result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lat += dlat; shift = 0; result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lng += dlng; LatLng p = new LatLng( (((double) lat / 1E5)), (((double) lng / 1E5) )); poly.add(p); } return poly; } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; LatLng latLng = new LatLng(-34, 151); mMap.addMarker(new MarkerOptions().position(latLng).draggable(true)); mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); mMap.setOnMarkerDragListener(this); mMap.setOnMapLongClickListener(this); } @Override public void onConnected(Bundle bundle) { getCurrentLocation(); } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } @Override public void onMapLongClick(LatLng latLng) { //Clearing all the markers mMap.clear(); //Adding a new marker to the current pressed position mMap.addMarker(new MarkerOptions() .position(latLng) .draggable(true)); latitude = latLng.latitude; longitude = latLng.longitude; } @Override public void onMarkerDragStart(Marker marker) { } @Override public void onMarkerDrag(Marker marker) { } @Override public void onMarkerDragEnd(Marker marker) { //Getting the coordinates latitude = marker.getPosition().latitude; longitude = marker.getPosition().longitude; //Moving the map moveMap(); } @Override public void onClick(View v) { if(v == buttonSetFrom){ fromLatitude = latitude; fromLongitude = longitude; Toast.makeText(this,"From set",Toast.LENGTH_SHORT).show(); } if(v == buttonSetTo){ toLatitude = latitude; toLongitude = longitude; Toast.makeText(this,"To set",Toast.LENGTH_SHORT).show(); } if(v == buttonCalcDistance){ getDirection(); } } }
در نهایت برای این برنامه شما باید اجازه زیر را بهAndroidManifest.xml اضافه کنید.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" />
حالا میتوانید برنامه خود را اجرا کنید.