Android Very Simple Book برمجة أندرويد
Android Very Simple Book برمجة أندرويد
(2010 / (2011 /
) )
( ( ( )
) )
(Mash up)
(2009)
(2010)
(4)
.
4
(
(Android)
(2005) .(2007) (Open Handset Alliance) (OHA) (48) (2008) (2009) .( ) . (HTC) (Android) (T-Mobile) (HTC)
Linux 2.6 ) (GNU/Linux) (kernel glibc ) (native windowing system) (GNU/Linux) (support memory ) (security) process ) (management network ) (management (driver model) (stack . (abstraction layer)
(GPS) . (accelerometer) .. (Linux Kernel) : Display Driver Bluetooth Driver Camera Driver
7
Flash Memory Driver Binder (IPC) Driver Keypad Driver USB Driver Wi-Fi Driver Audio Driver Power Management
: Dalvik Virtual Machine Core Libraries : Surface Manager Media Framework SQLite OpenGL ES Free Type Web Kit SGL SSL Libbc
: Activity Manager Window Manager Content Provider View System Notification Manager Package Manager Telephony Manager Resource Location Manager Sensor Manager
10
(Start)
: : On Save Instance State On Resume On Stop : On Destroy On Start On Restart On Resume On Push On Save Instance State
(Running)
(Paused)
(Destroyed)
(Intent)
.
12
(Service)
(Linear Layout)
vertical or ) .(horizontal
13
(A)
.(HTML)
14
SDK (Software Development Kit) \ . NDA (Native Development Kit) ADT (Android Development Tools) JDK (Java Development Kit) JRE (Java Runtime Environment) JVM (Java Virtual Machine) AVD (Android Virtual Device) AVDM (Android Virtual Device Manager) APK (Android Package)
15
DDMS (Dalvik Debug Monitor Server) GPS (Global Position System) CMD (Command Line) ADB (Android Debug Bridge)
16
17
(Java SE) Java ) (Java SE) (JDK 6) (Standard Edition ((Java Development Kit (JDK) (Java Runtime Environment) (JRE) (JDK) (JRE) : http://java.sun.com/javase/downloads/index.jsp
(Windows)
18
(Skip)
(Save)
20
(70)
(Accept)
21
(Next)
22
(Next)
23
(Finish)
24
http://developer.android.com/sdk/index.html
(Windows)
25
(Download)
(:(Save)
26
(Save)
(22)
(WinZip) (Windows)
27
(Copy) (Paste)
(android-sdk-windows)
28
(SDK Setup)
(https)
29
(Close)
(Cancel) (Settings)
30
(Available Packages)
(1.6)
31
(2.1)
. (1.5)
(Install Selected)
32
..
33
. :
http://www.Eclipsee.org/downloads
34
(Torrent)
(Save)
35
(Save)
Eclipsee-SDK-3.5.2-) (win32
36
(Copy) : (Paste)
(Eclipse)
37
38
(OK)
39
(welcome) (X)
40
(Help)
41
(Add)
(Name)
(Android) (Location)
/https://dl-ssl.google.com/android/Eclipsee (OK)
42
43
(Next)
44
(I accept) (Finish)
(Eclipse)
45
. (Preferences) : window
46
47
(Android) :
(Browse)
48
(OK) :
49
(Apply) :
.
50
(Hell World) ( . ( ) )
. (Eclipse)
51
New )
(New)
(File) (Project
52
(Next)
53
(1.6) :
Project Nam: AndroidVerySimple Build Target: 1.6 Application Name:VerySimple Package name:com.book.VerySimple Create Activity:Activity_VerySimple
54
(Finish)
(Layout)
55
(Res) (main.xml)
Hello ) (World
56
(Eclipse)
(Properties) (Advanced)
57
(Environment Variables)
58
(Path)
(UserName) (tools)
59
(OK)
60
(OK) (OK)
(CMD)
61
(OK)
62
(1)
63
(-p)
(-t)
(Target)
(Enter)
(c:\1)
64
(Eclipse)
C:\Documents and Settings\UserName\workspace
65
66
(sdk-windows
67
68
(Hardware) (New)
69
(Create AVD)
(OK)
70
(Start) (Launch)
71
72
(HelloWorld)
73
(Clean)
(Project)
74
(OK)
(X) .
75
Environment ) (Variables
(OK)
76
Android h (enter)
(h)
77
78
(VM_Android1.6) (avd -n
(No)
(yes)
79
: (VM_Android1.6)
(VM_Android1.6_1)
(SDK Setup) .
81
) DroidSans-Bold.ttf, : (DroidSansFallback.ttf, DroidSans.ttf adb remount adb shell rm /system/fonts/* adb push c:\fontss\DroidSans-Bold.ttf /system/fonts/ adb push c:\fontss\DroidSansFallback.ttf /system/fonts/ adb push c:\fontss\DroidSans.ttf /system/fonts/
82
(DDMS)
83
(DDMS) (Java)
(DDMS)
84
(File Explorer) (Heap) (Threads) (Allocation Tracker) (File Explorer) (sd card) . : ( ) . (Devices) USB )
85
(SDK) . Emulator )
(Driver
(Control
86
(Browser)
87
(Google.com in English)
88
(slideme.org)
89
(SAM v2.42)
90
91
(Done)
92
(Settings)
93
(Applications)
(Unknown sources)
(Development)
94
(DDMS)
(Slide Me)
95
(slideme.org)
OI Shopping )
(Utilities) (List
96
97
(Install) (Notifications)
98
(Install)
(Open) (apk) (Download) (SD Card) Slide Me (Apps Installer) (apk) (Slide Me)
99
android-sdk-windows\platforms\android-1.6\skins\HVGA
100
101
102
103
( (res)
) (layout) (main.xml)
104
(main.xml)
(Portrait)
(Landscape)
(Config)
105
(Layout) (Views)
106
1 <?xml version="1.0" encoding="utf-8"?> 2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/andr oid" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 > 7 <TextView 8 android:layout_width="fill_parent" 9 android:layout_height="wrap_content" 10 android:text="@string/hello" 11 /> 12 </LinearLayout> 107
108
(UTF-8)
(XML)
(6)
(2)
(LinearLayout) (4)
(LinearLayout) (orientation)
(layout_width)
(11)
(7)
(layout_height)
(text) (@string/hello)
12 </LinearLayout>
(LinearLayout)
(12)
(TextView) (res) ()
111
(Value)
112
(Task List)
(add)
113
(OK)
(color)
114
(Green) (Blue)
(string.xml)
(main.xml) (layout)
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" android:background="@color/TextViewBackColor"
/>
(background) (TextViewBackColor)
115
(String) (String)
116
(TextView) (MainTextView)
117
(main.xml)
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Task List" android:background="@color/TextViewBackColor" android:id="@+id/MainTextView"/>
android:id="@+id/MainTextView"
118
(MainTextView)
(Relative)
(@+id/)
@id/MainTextView (+)
(Title) (Details)
119
(Menu)
import android.widget.TextView;
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.Menu; import android.widget.TextView; public class Activity_TaskList extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { 120
super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
(activities,alertdialog,toast)
(Welcome)
Toast.makeText(Activity_TaskList.this,"Welcome",0).show() ; 121
TextView[] tvs; tvs = new TextView[10]; for (int i=0; i<10; ++i) { tvs[i] = new TextView(this); tvs[i].setText("hi"); } }
(Menu) (Save)
@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuItem item1 = menu.add(0, 1, 0, "Save"); item1.setIcon(android.R.drawable.ic_menu_save ); return true; }
@Override public boolean onOptionsItemSelected(MenuItem item) { TextView MainTextView = (TextView)findViewById(R.id.MainTextView); switch (item.getItemId()) { case 1 : Log.v("Task:",MainTextView.getText().toString()); return true; } return false; }
123
(50)
124
keytool -genkey -v -keystore badwi.keystore -alias badwi -keyalg RSA -keysize 2048 -validity 10000 (badwi)
(badwi.keystore) :
Windows Vista or 7: C:\Users\<user>\.android\badwi.keystore Windows XP: C:\Documents and Settings\<user>\.android\badwi.keystore
125
126
127
http://market.android.com/publish/Home
(Upload Application)
128
129
130
131
132
RestDroid-mini
133
RestDroid-mini
RestDroid . . . RestDroid RestDroid-mini. : API : . . ) ). . . ) ). . : API. . : 134 RestDroid
: http://www.youtube.com/watch?v=BEDuS6gq4JA
. .
:
: : . : . + + ( ) .( : . Classes . ) ( 135 Methods ) .
) ( :
XML XML
Best50
intro ViewOnMapActivity.
137
AddressOverlay.java . .
138
Application Application -
:
File>new>project Android Project Android
139
140
141
UTF-8 Properties:
142
intro:
Class
143
android.app.Activity ) ) ( main.xml . .
144
colors.xml values ). :
. strings.xml
. : <!---> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/background"> main.xml
<Button android:id="@+id/search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/ImageView01" android:paddingLeft="20px" android:paddingRight="20px" android:layout_centerInParent="true" android:layout_marginTop="20px" /> </RelativeLayout> </LinearLayout> . ) ). RelativeLayout LinearLayout . 147 ImageView res/drawable res/drawable-hdpi
RelativeLayout ( ) . android:layout_below . .
Layout
):
intro . )
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class intro extends Activity { // private Button getbest50; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); main // setContentView(R.layout.main); setUpViews(); } private void setUpViews() { getbest50 = (Button)findViewById(R.id.search); "); getbest50.setText(" // getbest50.setOnClickListener(new View.OnClickListener() { public void onClick(View v) 149
: . intro.java ( ( : package android.prog.easily; import java.io.Serializable; public class RatedItem implements Serializable { private static final long serialVersionUID = 5500258407135652423L; 150 RatedItem.java
private String name; private int id; private int voteCount; private double wScore; public RatedItem(String name, int id, int voteCount, double wScore) { this.name = name; this.id = id; this.voteCount = voteCount; this.wScore = wScore; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { 151
this.id = id; } public int getVoteCount() { return voteCount; } public void setVoteCount(int voteCount) { this.voteCount = voteCount; } public double getwScore() { return wScore; } public void setwScore(int wScore) { this.wScore = wScore; } }
: package android.prog.easily; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; import android.app.Application; public class RestDroidApplication extends Application { // Qaym API Key private String key = "xxxxxxxxxxxxxxxxxxxx"; private int[] countryAndCityIds; private JSONObject[] ratedRestaurants; private ArrayList<RatedItem> globalAdapterData; private RatedItem itemOnMap; private String branchesDetailsText;
{ return branchesDetailsText; } public void setBranchesDetailsText(String branchesDetailsText) { this.branchesDetailsText = branchesDetailsText; } public RatedItem getItemOnMap() { return itemOnMap; } public void setItemOnMap(RatedItem itemOnMap) { this.itemOnMap = itemOnMap; } @Override public void onCreate() { super.onCreate(); } @Override public void onTerminate() { super.onTerminate(); } 154
HTTP REST public String queryRESTurl(String url) { HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet(url); HttpResponse response; try { response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); String result1 = convertStreamToString(instream); instream.close(); return result1; } } catch (IOException e) 155
//
public String convertStreamToString(InputStream is) throws IOException { if (is != null) { StringBuilder sb = new StringBuilder(); String line; try { BufferedReader reader = new BufferedReader(new while ((line = reader.readLine()) != null) { sb.append(line).append("\n"); } } finally { is.close(); } 156
JSON Key/value .. ..( ) " " JSON */ public JSONObject[] retrieveJSONs(String urlString) { String result = queryRESTurl(urlString); JSONObject[] jarr = null; if (result != null) { try { result = result.substring(1, result.length()1); 157
int counter = 0; boolean firstSeen = false; boolean secondSeen = false; for JSON for (int i = 0; i < result.length(); i++) { if (result.charAt(i) == '{' && firstSeen == { firstSeen = true; counter++; } else if (result.charAt(i) == '{' && firstSeen == true) { secondSeen = true; } if (result.charAt(i) == '}' && secondSeen == true) { secondSeen = false; } else if (result.charAt(i) == '}' && secondSeen == false) { firstSeen = false; 158 //
} } jarr = new JSONObject [counter]; int ind1 = 0; int ind2 = 0; boolean firstSeenS = false; boolean secondSeenS = false; JSON // for (int i = 0; i < result.length(); i++) { firstSeenS = false; secondSeenS = false; if (result.charAt(i) == '{' && firstSeenS false) == { firstSeenS = true; ind1 = i; for (int j = i+1; j < result.length(); j++) { if (result.charAt(j) == '{' && { secondSeenS = true; } 159
if (result.charAt(j) == '}' && { secondSeenS = false; } else if (result.charAt(j) == '}' && secondSeenS == false) { String mid = jarr[ind2] = new ind2++; i = j; break; } } } } } catch (JSONException e) { } } return jarr; } API // public String getUrlStringCommand(String command) 160
{ String service_url = "http://api.qaym.com/0.1/"; String url = ""; url = service_url + command + "/key=" + key; return url; } public void setCountryAndCityIds(int[] countryAndCityIds) { this.countryAndCityIds = countryAndCityIds; } public int[] getCountryAndCityIds() { return countryAndCityIds; } public JSONObject[] getRatedRestaurants() { return ratedRestaurants; } public void setRatedRestaurants(JSONObject[] ratedRestaurants) { this.ratedRestaurants = ratedRestaurants; } public ArrayList<RatedItem> getGlobalAdapterData() 161
{ return globalAdapterData; } public void setGlobalAdapterData(ArrayList<RatedItem> globalAdapter) { this.globalAdapterData = globalAdapter; } public RatedItem getGlobalAdapterDataItem(int position) { return globalAdapterData.get(position); } }
: protected void top50Handler() { try { API // " " String attrcommand = "cities/" + "57" + "/items/top"; 162
intro.java
// accessApplicationMethods() RestDroidApplication.java String attributesCommand = accessApplicationMethods().getUrlStringCommand(attrcom mand); JSONObject[] topCities = accessApplicationMethods().retrieveJSONs(attributesComma nd); // \ JSON ArrayList<RatedItem> sRest = new ArrayList<RatedItem>(); if (topCities != null) { for (int ff = 0; ff < topCities.length; ff++) { // "item_id" JSON int id = Integer.parseInt(topCities[ff].getString("item_id")); 163 ReatedItem
String name = topCities[ff].getString("item_name"); int voteConutt = Integer.parseInt(topCities[ff].getString("total_number_of_vot es")); double weScore = Double.parseDouble(topCities[ff].getString("weighted_score ")); // double weScoreR = weScore * 100; weScoreR = Math.round(weScoreR); weScoreR = weScoreR / 10 / 2; RatedItem singleRest = new id, voteConutt, weScoreR); sRest.add(singleRest); } } else { RatedItem singleRest = new 0, 0, 0); sRest.add(singleRest); } 164
RatedItem(name,
RatedItem("Empty List",
accessApplicationMethods().setGlobalAdapterData(sRest); // *** goToBest50Act(); } catch (JSONException e) { } } // RestDroidApplication.java protected RestDroidApplication accessApplicationMethods() { return (RestDroidApplication)getApplication(); }
. : // *** : goToBest50Act
protected void goToBest50Act() { Intent goToBest = new Intent(this, Best50.class); startActivity(goToBest); } 165
: package android.prog.easily; import java.util.ArrayList; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class intro extends Activity { // private Button getbest50;
intro.java
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); main // setContentView(R.layout.main); setUpViews(); } private void setUpViews() 166
{ getbest50 = (Button)findViewById(R.id.search);
setText(" // getbest50.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { top50Handler(); } }); } protected void goToBest50Act() { Intent goToBest = new Intent(this, Best50.class); startActivity(goToBest); } protected void top50Handler() { try { API // " " String attrcommand = "cities/" + "57" + "/items/top"; 167
// accessApplicationMethods() RestDroidApplication.java String attributesCommand = accessApplicationMethods().getUrlStringCommand(attrcom mand); JSONObject[] topCities = accessApplicationMethods().retrieveJSONs(attributesComma nd); // \ JSON ArrayList<RatedItem> sRest = new ArrayList<RatedItem>(); if (topCities != null) { for (int ff = 0; ff < topCities.length; ff++) { // "item_id" JSON int id = Integer.parseInt(topCities[ff].getString("item_id")); String name = topCities[ff].getString("item_name"); int voteConutt = 168 ReatedItem
Integer.parseInt(topCities[ff].getString("total_number_of_vot es")); double weScore = Double.parseDouble(topCities[ff].getString("weighted_score ")); // double weScoreR = weScore * 100; weScoreR = Math.round(weScoreR); weScoreR = weScoreR / 10 / 2; RatedItem singleRest = new id, voteConutt, weScoreR); sRest.add(singleRest); } } else { RatedItem singleRest = new 0, 0, 0); sRest.add(singleRest); }
RatedItem(name,
RatedItem("Empty List",
accessApplicationMethods().setGlobalAdapterData(sRest); goToBest50Act(); } catch (JSONException e) { } } // RestDroidApplication.java protected RestDroidApplication accessApplicationMethods() { return (RestDroidApplication)getApplication(); } }
170
RatedRestaurantListItem.java
package android.prog.easily; import android.content.Context; import android.util.AttributeSet; import android.widget.RelativeLayout; public class RatedRestaurantListItem extends RelativeLayout { public RatedRestaurantListItem(Context context, AttributeSet attr) { super(context, attr); } } : 171 rest_list_item.xml
):
layout ( ) )
res>layout ( new>file).
<?xml version="1.0" encoding="utf-8"?> <android.prog.easily.RatedRestaurantListItem xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!--> <CheckedTextView android:layout_width="wrap_content" android:id="@+id/ctext" android:layout_height="wrap_content" android:textSize="30sp" > </CheckedTextView> <!---> <RatingBar android:id="@+id/rate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/ctext" android:numStars="5" style="?android:attr/ratingBarStyleIndicator" /> 172
-->
<TextView android:id="@+id/scorelabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/rate" android:textSize="20sp" android:paddingTop="10px" android:paddingRight="10px" /> </android.prog.easily.RatedRestaurantListItem>
RatedRestaurantListItem.java : 173 .( )
package android.prog.easily; import android.prog.easily.R; import android.content.Context; import android.util.AttributeSet; import android.widget.CheckedTextView; import android.widget.RelativeLayout; import android.widget.TextView; public class RatedRestaurantListItem extends RelativeLayout { private CheckedTextView ratedButton; private RatedItem ratedItem1; private TextView texty; private TextView texty2; public RatedRestaurantListItem(Context context, AttributeSet attr) { super(context, attr); } // xml @Override protected void onFinishInflate() { super.onFinishInflate(); ratedButton = (CheckedTextView)findViewById(R.id.ctext); 174
texty = (TextView)findViewById(R.id.ratedlabel); texty2 = (TextView)findViewById(R.id.scorelabel); } // public void setRatedItem(RatedItem ratedItem1) { this.ratedItem1 = ratedItem1; ratedButton.setText(ratedItem1.getName()); : texty.setText(" "+ratedItem1.getVoteCount()); : "+ratedItem1.getwScore() texty2.setText(" + "/5"); } public RatedItem getRatedItem() { return ratedItem1; } } : Best50.java rated_rest_list.xml :
xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/RRselect" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <ListView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@id/android:list" android:layout_below="@id/RRselect"/> </RelativeLayout> Best50.java. . Activity ListActivity Design Patterns . ( ) Best50). Best50 Best50.java. ( 176 ) ) \ intro.java. List Adapter
! inner class . : package android.prog.easily; import java.util.ArrayList; import android.app.Activity; import android.app.ListActivity; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.RatingBar; import android.widget.TextView; public class Best50 extends ListActivity { private TextView selectAttr; private RatedRestaurantListAdapter adapter; @Override public void onCreate(Bundle savedInstanceState) { 177
super.onCreate(savedInstanceState); setContentView(R.layout.rated_rest_list); setUpViews(); } // @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); RatedItem ite = accessApplicationMethods().getGlobalAdapterDataItem(posi tion); accessApplicationMethods().setItemOnMap(ite); goToViewOnMapActivity(); } private void goToViewOnMapActivity() { Intent goToMapActivity = new Intent(this, startActivity(goToMapActivity); } private void setUpViews() 178
{ selectAttr = (TextView)findViewById(R.id.RRselect); "); selectAttr.setText(" // adapter = new RatedRestaurantListAdapter setListAdapter(adapter); } Adapter . // ArrayAdapter class RatedRestaurantListAdapter extends ArrayAdapter<RatedItem> { Activity context; private ArrayList<RatedItem> myRatedItems; RatedRestaurantListAdapter(Activity context, { super(context, R.layout.rest_list_item, items); this.context=context; this.myRatedItems = items; } // public View getView(int position, View 179 InnerClass //
parent) {
convertView, ViewGroup
//
rateBar.setRating((float)myRatedItems.get(position).getwSco 180
re()); return row; } public RatedItem getItem(int position) { return myRatedItems.get(position); } public void reload() { // notifyDataSetChanged(); } } protected RestDroidApplication accessApplicationMethods() { return (RestDroidApplication)getApplication(); } } OnListItemClick . ) position 181
. ( .
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/restaurantNameMap" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="30sp" /> <com.google.android.maps.MapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@id/restaurantNameMap" android:clickable="true" android:apiKey="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 182
debugging )
$ keytool -list -alias androiddebugkey \ -keystore xxx \ -storepass android -keypass android :
Windows XP: C:\Documents
xxx
API xxxxxxxxxx.
: http://code.google.com/android/add-ons/googleapis/mapkey.html
ViewOnMapActivity.java : AddressOverlay.java: package android.prog.easily; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.location.Address; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import com.google.android.maps.Projection; public class AddressOverlay extends Overlay { private static final int CONTAINER_RADIUS private static final int = 1; CONTAINER_SHADOW_OFFSET 184
private Address address; private GeoPoint geopoint; Bitmap bb; public AddressOverlay(Address address) { super(); assert(null != address); // this.setAddress(address); Double convertedLongitude = address.getLongitude() * 1E6; Double convertedLatitude = address.getLatitude() * 1E6; setGeopoint(new GeoPoint( convertedLatitude.intValue(), convertedLongitude.intValue())); } // @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { super.draw(canvas, mapView, shadow); Point locationPoint = new Point(); Projection projection = mapView.getProjection(); projection.toPixels(getGeopoint(), locationPoint); Paint containerPaint = new Paint(); containerPaint.setAntiAlias(true); 185
int containerX = locationPoint.x; int containerY = locationPoint.y; if (shadow) { containerX += CONTAINER_SHADOW_OFFSET; containerY += CONTAINER_SHADOW_OFFSET; containerPaint.setARGB(90, 0, 0, 0); canvas.drawCircle(containerX, containerY, CONTAINER_RADIUS, containerPaint); } else { containerPaint.setColor(Color.GREEN); canvas.drawCircle(containerX, containerY, CONTAINER_RADIUS, containerPaint); } } public void setAddress(Address address) { this.address = address; } public Address getAddress() { return address; } 186
public void setGeopoint(GeoPoint geopoint) { this.geopoint = geopoint; } public GeoPoint getGeopoint() { return geopoint; } }
ViewOnMapActivity.java: package android.prog.easily; import java.io.IOException; import java.util.List; import org.json.JSONException; import org.json.JSONObject; import android.graphics.Bitmap; import android.location.Address; import android.location.Geocoder; import android.os.Bundle; import android.widget.TextView; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; 187
import com.google.android.maps.MapController; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; public class ViewOnMapActivity extends MapActivity { public static final String ADDRESS_RESULT = "address";
private MapView mapView; private Address address; private TextView restName; private JSONObject[] restaurantsLocObjects; private String[] restaurantsBranchesNames; private double [][] longLat; private int maxLat = 0; private int minLat = 0; private int maxLon = 0; private int minLon = 0; Bitmap bmp; @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.view_map); setUpViews(); bringRestLocations(); 188
mapCurrentAddress(); } // private void bringRestLocations() { try { ID // Best50.java RestDroidApplication int restNum = accessApplicationMethods().getItemOnMap().getId(); API //
String command = "items/" + restNum + "/locations"; String restaurantsCommand = accessApplicationMethods().getUrlStringCommand(comman d); restaurantsLocObjects = accessApplicationMethods().retrieveJSONs(restaurantsCom mand); restaurantsBranchesNames = new String[restaurantsLocObjects.length]; longLat = new double[restaurantsLocObjects.length][2]; 189
for (int i = 0; i < restaurantsBranchesNames.length; i++) { restaurantsBranchesNames[i] = (i+1) " + + "\n" +" : restaurantsLocObjects[i].getString("country") + "\n" :" +" + restaurantsLocObjects[i].getString("city") + "\n" :" +" + restaurantsLocObjects[i].getString("location_id") + "\n" +" :" + restaurantsLocObjects[i].getString("address") + "\n" +" :" + restaurantsLocObjects[i].getString("phone") + "\n" :" +" + restaurantsLocObjects[i].getString("title") + "\n"; longLat[i][0] = Double.parseDouble(restaurantsLocObjects[i].getString("latit ude")); longLat[i][1] = Double.parseDouble(restaurantsLocObjects[i].getString("lon gitude")); } 190
} catch (JSONException e) { } } // protected void mapCurrentAddress() { Geocoder g = new Geocoder(this); List<Address> addresses; boolean firstTime = true; for (int i = 0; i < restaurantsBranchesNames.length; i++) { try { addresses = g.getFromLocation(longLat[i][0], longLat[i][1], 1); if (addresses.size() > 0) { address = addresses.get(0); List<Overlay> mapOverlays = mapView.getOverlays(); AddressOverlay addressOverlay = new AddressOverlay(address); 191
mapOverlays.add(addressOverlay); // zoom //
if (firstTime) { minLat = addressOverlay.getGeopoint().getLatitudeE6(); maxLat = addressOverlay.getGeopoint().getLatitudeE6(); minLon = addressOverlay.getGeopoint().getLongitudeE6(); maxLon = addressOverlay.getGeopoint().getLongitudeE6(); firstTime = false; } minLat = (minLat > addressOverlay.getGeopoint().getLatitudeE6()) ? addressOverlay.getGeopoint().getLatitudeE6() : minLat; maxLat = (maxLat < addressOverlay.getGeopoint().getLatitudeE6()) ? addressOverlay.getGeopoint().getLatitudeE6() : maxLat; minLon = (minLon > addressOverlay.getGeopoint().getLongitudeE6()) ? 192
addressOverlay.getGeopoint().getLongitudeE6() : minLon; maxLon = (maxLon < addressOverlay.getGeopoint().getLongitudeE6()) ? addressOverlay.getGeopoint().getLongitudeE6() : maxLon; mapView.invalidate(); } else { } } catch (IOException e) { } } final MapController mapController = mapView.getController(); GeoPoint center = new GeoPoint((maxLat + minLat)/2,(maxLon + minLon)/2); mapController.animateTo(center, new Runnable() { public void run() { mapController.zoomToSpan(maxLat minLat,maxLon - minLon); } 193
restName.setText(accessApplicationMethods().getItemOnMa p().getName()); mapView = (MapView)findViewById(R.id.map); Zoomin/out // mapView.setBuiltInZoomControls(true); } @Override protected boolean isLocationDisplayed() { return true; } @Override protected boolean isRouteDisplayed() { return false; } protected RestDroidApplication 194
195
AndroidManifest.xml 196
..
. . : <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.prog.easily" android:versionCode="1" android:versionName="1.0"> <!---> <application android:name=".RestDroidApplication" android:icon="@drawable/icon" android:label="@string/app_name"> <!-" " .java --> <activity android:name=".intro" android:label="@string/app_name"> <!---> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> 197
</intent-filter>
</activity> <activity android:name=".Best50" android:label="Best 50 rest"> </activity> <activity android:name=".ViewOnMapActivity" android:label="view on Map"> </activity>
<!---> <uses-library android:name="com.google.android.maps" /> </application> <!---> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCAT ION" /> <!-- --> <uses-sdk android:minSdkVersion="7" /> 198
</manifest>
199
200
201
202
:
( ) : $ cd /Developer/android-sdk-mac_86/tools/ $ ./adb devices : List of devices attached emulator-5554 device ( : $ cd /Developer/android-sdk-mac_86/tools/ $ ./emulator -avd GPSenables -partition-size 500 -avd \ GPSenables . ) -
. ) ( : 203 -
$ ./adb remount
remount succeeded ): )
$ ./adb push /Users/wa2el/Desktop/fontss/DroidSans-Bold.ttf /system/fonts/ $ ./adb push /Users/wa2el/Desktop/fontss/DroidSans.ttf /system/fonts/ $ ./adb push /Users/wa2el/Desktop/fontss/DroidSansFallback.ttf /system/fonts/
xml) . )
204
:
: <LinearLayout> <TableLayout> <ScrollView> <LinearLayout> \ -
: <LinearLayout
205
layout_width fill_parent. layout_height . . <Button android:text="@+id/Button01" android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content"> </Button> android:text . android:id . fill_parent . .
206
wrap_content .
layout_height). . ) ):
(layout_width
207
Layout .. XML )
android:layout_height="100px"> </Button>
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" > </Button> <Button android:text="Ardroid" android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="2" > </Button>
211
Widgets
android:layout_gravity android:orientation=vertical: <Button android:text="Ardroid" android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" > 213
</Button>
android:gravity . \ . .
android:paddingLeft
Orientation
x.setOrientation(LinearLayout.HORIZONTAL); 214
Widget <TableLayout>
x -
>TableRow< :
) . .
215
android:stretchColumns="2" > <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!" android:layout_column="2" android:layout_gravity="center" /> </TableRow> <TableRow> <SeekBar android:id="@+id/SeekBar01" 217
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_span="2" android:layout_column="1"> </SeekBar> </TableRow> <TableRow> <Button android:text="Ardroid" android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_column="2" > 218
</Button> <CheckBox android:text="checkBox" android:id="@+id/CheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_column="0" > </CheckBox> </TableRow> <TableRow> <RadioButton android:text="Radio Button" android:id="@+id/RadioButton01" 219
android:layout_width="wrap_content" android:layout_height="wrap_content" > </RadioButton> </TableRow> </TableLayout> <ScrollView> . . Widgets ). <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" 220 ) -
android:layout_height="wrap_content"> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:stretchColumns="2" > <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!" android:layout_column="2" 221
android:layout_gravity="center" /> </TableRow> <TableRow> <SeekBar android:id="@+id/SeekBar01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_span="2" android:layout_column="1"> </SeekBar> </TableRow> <TableRow> <Button 222
android:text="Ardroid" android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_column="2" > </Button> <CheckBox android:text="checkBox" android:id="@+id/CheckBox01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_column="0" > 223
</CheckBox> </TableRow> <TableRow> <RadioButton android:text="Radio Button" android:id="@+id/RadioButton01" android:layout_width="wrap_content" android:layout_height="wrap_content" > </RadioButton> </TableRow> <TableRow> <RadioButton android:text="Radio Button" 224
android:id="@+id/RadioButton01" android:layout_width="wrap_content" android:layout_height="wrap_content" > </RadioButton> </TableRow> <TableRow> <RadioButton android:text="Radio Button" android:id="@+id/RadioButton01" android:layout_width="wrap_content" android:layout_height="wrap_content" > </RadioButton> 225
</TableRow> <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!" android:layout_column="2" android:layout_gravity="center" /> </TableRow> <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" 226
android:text="Hello!" android:layout_column="2" android:layout_gravity="center" /> </TableRow> <TableRow> <SeekBar android:id="@+id/SeekBar01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_span="2" android:layout_column="1"> </SeekBar> </TableRow> 227
<TableRow> <SeekBar android:id="@+id/SeekBar01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_span="2" android:layout_column="1"> </SeekBar> </TableRow> <TableRow> <SeekBar android:id="@+id/SeekBar01" android:layout_width="wrap_content" android:layout_height="wrap_content" 228
229
230