'개발'에 해당되는 글 188건
- 2010.03.26 안드로이드 폰 화면 사이즈 구하기
- 2010.03.23 Understanding User Interface in Android - Part 2: Views 7
- 2010.03.23 Dialog App
- 2010.03.16 안드로이드 AVD SDcard Mount 방법
- 2010.02.10 안드로이드 에뮬레이터 host 수정법 4
- 2010.02.04 자료 보관할 내용. 1
- 2010.02.03 안드로이드 위젯에서 Activity 호출하기. 17
- 2010.02.02 How to make a simple Android widget 5
- 2010.01.28 Using Google Maps in Android 63
- 2010.01.22 A Visual Guide to Android GUI Widgets
안드로이드 폰 화면 사이즈 구하기
폰 사이즈 구하기는 그냥 숫자만 봐도 알겠는데..
PixeFormat에 관련된 숫자가 의미하는건 모르겠다 -_-;;
view plaincopy to clipboardprint?
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int displayWidth = display.getWidth();
int displayHeight = display.getHeight();
int displayOrientation = display.getOrientation();
int displayPixelFormat = display.getPixelFormat();
float displayRefreshRate = display.getRefreshRate();
System.out.println("displayWidth : " + displayWidth);
System.out.println("displayHeight : " + displayHeight);
System.out.println("displayOrientation : " + displayOrientation);
System.out.println("displayPixelFormat : " + displayPixelFormat);
System.out.println("displayRefreshRate : " + displayRefreshRate);
// 결과
// displayWidth : 240
// displayHeight : 400
// displayOrientation : 0 //0:세로, 1: 가로
// displayPixelFormat : 4 // ??
// displayRefreshRate : 60.0
Understanding User Interface in Android - Part 2: Views
In the previous article on Android UI you saw the components that make up the UI of an Android application. The basic unit of the Android UI is the View. A View represents a widget that has an appearance on the screen. In this article (and the next two), you will learn about the various common views that you would likely use in your journey of Android development. In particular, I have categorized the views in this series into the following group:
- Basic Views - commonly-used views such as TextView, EditText, and Button views
- Picker Views - views that allows users to select from, such as the TimePicker and DatePicker views
- List Views - views that display a long list of items, such as the ListView and the Spinner views
- Display Views - views that display images, such as the Gallery and ImageSwitcher views
- Menus - views that displays additional and context sensitive menu items
- Additional Views - interesting views such as the AnalogClock and DigitalClock views
In this article, I will cover the first group - Basic Views. The next article will cover the Picker Views and List Views. Lastly, the third article will cover the Menus and additional views.
For all the examples in this article, you shall create a new Android project using Eclipse. Name the project as shown in Figure 1.
Basic Views
In this section, you will examine the basic views in Android that allow you to display text information as well as perform some basic selection. In particular, you will learn about the following views:
- TextView
- EditText
- Button
- ImageButton
- CheckBox
- ToggleButton
- RadioButton
- RadioGroup
TextView View
When you create a new Android project, Eclipse always creates the main.xml
file (located in the res/layout
folder) containing a <TextView>
element:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout>
The TextView
view is used to display text to the user. This is the most basic view that you will definitely come across when you develop Android applications. If you need to allow users to edit the text displayed, you should use the subclass of TextView
- EditText
, which is discussed in the next section.
Button
, ImageButton
, EditText
, CheckBox
, ToggleButton
, RadioButton
, and RadioGroup
Views
Besides the TextView
view, which you will come across the most often, there are some other basic controls that you will find yourself using very often. They are: Button
, ImageButton
, EditText
, CheckBox
, ToggleButton
, RadioButton
, and RadioGroup
.
First, add a new file to the res/layout
folder and name it as basicviews.xml
. Populate it with the following elements:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/btnSave" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Save" /> <Button android:id="@+id/btnOpen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Open" /> <ImageButton android:id="@+id/btnImg1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:src="@drawable/icon" /> <EditText android:id="@+id/txtName" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <CheckBox android:id="@+id/chkAutosave" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Autosave" /> <CheckBox android:id="@+id/star" style="?android:attr/starStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <RadioGroup android:id="@+id/rdbGp1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <RadioButton android:id="@+id/rdb1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Option 1" /> <RadioButton android:id="@+id/rdb2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Option 2" /> </RadioGroup> <ToggleButton android:id="@+id/toggle1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
Note that you use the id attribute to identify each view. The id of a view must start with the "@+id/" specifier followed by the name of the view.
The above XML file contains the following views:
- Button - represents a push-button widget
- ImageButton - similar to the Button view, except that it also displays an image
- EditText - a subclass of the TextView view, except that it allows users to edit its text content
- CheckBox - a special type of button that has two states - checked or unchecked
- RadioGroup and RadioButton - the RadioButton has two states - either checked or unchecked. Once a RadioButton is checked, it cannot be unchecked. A RadioGroup is used to group together one or more RadioButton views, thereby allowing only one RadioButton to be checked within the RadioGroup
- ToggleButton - displays checked/unchecked states using a light indicator
Figure 2 shows how the various views will look like in their various states. In particular, the right side of the figure shows the CheckBox
, RadioButton
, and ToggleButton
views in their checked state.
To handle the various common events associated with the various views, add a new class to the src/net.learn2develop.AndroidViews
folder and name it as BasicViewsExample.java
. Code its content as follows:
package net.learn2develop.AndroidViews; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.RadioGroup; import android.widget.Toast; import android.widget.ToggleButton; import android.widget.RadioGroup.OnCheckedChangeListener; public class BasicViewsExample extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.basicviews); //---Button view--- Button btnOpen = (Button) findViewById(R.id.btnOpen); btnOpen.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Toast.makeText(getBaseContext(), "You have clicked the Open button", Toast.LENGTH_SHORT).show(); } }); Button btnSave = (Button) findViewById(R.id.btnSave); btnSave.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { DisplayToast("You have clicked the Save button"); } }); //---CheckBox--- CheckBox checkBox = (CheckBox) findViewById(R.id.chkAutosave); checkBox.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (((CheckBox)v).isChecked()) DisplayToast("CheckBox is checked"); else DisplayToast("CheckBox is unchecked"); } }); //---RadioButton--- RadioGroup radioGroup = (RadioGroup) findViewById(R.id.rdbGp1); radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(RadioGroup group, int checkedId) { //---displays the ID of the RadioButton that is checked--- DisplayToast(Integer.toString(checkedId)); } }); //---ToggleButton--- ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggle1); toggleButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (((ToggleButton)v).isChecked()) DisplayToast("Toggle button is On"); else DisplayToast("Toggle button is Off"); } }); } private void DisplayToast(String msg) { Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show(); } }
In particular, the above program displays a message (using the Toast
class) when the various controls are clicked.
Add the following lines in bold to the AndroidManifest.xml
file to register the new BasicViewsExample
activity:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.learn2develop.AndroidViews" android:versionCode="1" android:versionName="1.0.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ViewsActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".BasicViewsExample" android:label="@string/app_name" /> </application> </manifest>
To display the BasicViewsExample
activity, insert the following statements in bold in the ViewsActivity.java
file:
package net.learn2develop.AndroidViews; import android.app.Activity; import android.content.Intent; import android.os.Bundle; public class ViewsActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //---load the BasicViewsExample activity--- startActivity(new Intent(this, BasicViewsExample.class)); } }
To test the application, press F11
to debug the application on the Android emulator. Figure 3 shows the message displayed when the ToggleButton
is clicked.
For the EditText
view, you can also set it to accept passwords by replacing each character with a ".". This is done using the password attribute:
<EditText android:id="@+id/txtName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password = "true"
/>
Figure 4 shows that when you enter a string of text into the view, the character you enter always appears first and then changes into a "." when you enter the next character (or after one second if you do nothing).
ProgressBar View
The ProgressBar view provides visual feedback of some background tasks. For example, you might be downloading some data from the web and need to update the user of the status of the download. In this case, the ProgressBar view is a good choice for this task.
Using the same activity created in the previous section, insert the following element in the basicviews.xml
file:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ProgressBar android:id="@+id/progressbar" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/btnSave" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Save" /> <!- Other views omitted --> </LinearLayout>
The default mode of the ProgressBar
view is indeterminate - that is, it shows a cyclic animation. This mode is useful for tasks that do not have a clear indication of when they will be completed. For example, you are sending some data to a web service and waiting for the server to respond.
The following code shows how you can spin off a background thread to simulate performing some long lasting tasks. When the task is completed, you hide the ProgressBar view by setting its Visibility property to GONE (value 8).
import android.widget.ProgressBar; import android.os.Handler; public class BasicViewsExample extends Activity { private static int progress = 0; private ProgressBar progressBar; private int progressStatus = 0; private Handler handler = new Handler(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.basicviews); progressBar = (ProgressBar) findViewById(R.id.progressbar); //---do some work in background thread--- new Thread(new Runnable() { public void run() { //---do some work here--- while (progressStatus < 10) { progressStatus = doSomeWork(); } //---hides the progress bar--- handler.post(new Runnable() { public void run() { //---0 - VISIBLE; 4 - INVISIBLE; 8 - GONE--- progressBar.setVisibility(8); } }); } //---do some long lasting work here--- private int doSomeWork() { try { //---simulate doing some work--- Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } return ++progress; } }).start(); //... //... } //... }
The difference between the INVISIBLE
and GONE
constants is that the INVISIBLE
constant simply hides the ProgressBar
view. The GONE
constant removes the ProgressBar
view from the activity and does not take up any space on the activity.
The left of Figure 5 shows the ProgressBar
view in action. When the background task is completed, the space taken by the view is given up when you set its Visibility
property to GONE
.
If you do not want to display the ProgressBar
view in indeterminate mode, you can modify it to display as a horizontal bar. The following style attribute specifies the ProgressBar
view to be displayed as a horizontal bar:
<ProgressBar android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
/>
The following code causes the ProgressBar
view to increment from 1 to 100 and then disappears off the screen (see also Figure 6):
public class BasicViewsExample extends Activity { private static int progress = 0; private ProgressBar progressBar; private int progressStatus = 0; private Handler handler = new Handler(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.basicviews); progressBar = (ProgressBar) findViewById(R.id.progressbar); //---do some work in background thread--- new Thread(new Runnable() { public void run() { while (progressStatus < 100) { progressStatus = doSomeWork(); //---Update the progress bar--- handler.post(new Runnable() { public void run() { progressBar.setProgress(progressStatus); } }); } //---hides the progress bar--- handler.post(new Runnable() { public void run() { //---0 - VISIBLE; 4 - INVISIBLE; 8 - GONE--- progressBar.setVisibility(8); } }); } private int doSomeWork() { try { //---simulate doing some work--- Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } return ++progress; } }).start(); //... //... } }
AutoCompleteTextView View
The AutoCompleteTextView view is a view that is similar to the EditText
view (in fact it is a subclass of the EditText
view), except that it shows a list of completion suggestions automatically while the user is typing.
Add a new file to the res/layout
folder and name it as autocomplete.xml
and populate it with the following elements:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <AutoCompleteTextView android:id="@+id/txtCountries" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
Add a new file to the src/net.learn2develop.AndroidViews
folder and name it as AutoCompleteExample.java
. Populate it as follows:
package net.learn2develop.AndroidViews; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; public class AutoCompleteExample extends Activity { String[] presidents = { "Dwight D. Eisenhower", "John F. Kennedy", "Lyndon B. Johnson", "Richard Nixon", "Gerald Ford", "Jimmy Carter", "Ronald Reagan", "George H. W. Bush", "Bill Clinton", "George W. Bush", "Barack Obama" }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.autocomplete); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, presidents); AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.txtCountries); textView.setThreshold(3); textView.setAdapter(adapter); } }
Note that the list of suggestions is obtained from an ArrayAdapter
object. The setThreshold()
method sets the number of minimum number of characters the user must type before the suggestions appear as a drop-down menu.
Add the following lines in bold to the AndroidManifest.xml
file to register the new AutoCompleteExample
activity:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.learn2develop.AndroidViews" android:versionCode="1" android:versionName="1.0.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ViewsActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".AutoCompleteExample" android:label="@string/app_name" /> </application> </manifest>
Modify the ViewsActivity.java
file to start the AutoCompleteExample
activity:
package net.learn2develop.AndroidViews; import android.app.Activity; import android.content.Intent; import android.os.Bundle; public class ViewsActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); startActivity(new Intent(this, AutoCompleteExample.class)); } }
Figure 7 shows the AutoCompleteTextView
view in action when you enter some text into it.
Summary
In this article, you have seen some of the very common views that you will use in Android. In the next two articles, I will dive into more views that you can use in building your killer Android applications. Stay tuned for the next article, where I will discuss the various Picker and List views that you can use.
Dialog App
1. Activity를 Dialog화
다양한 형태의 UI화면을 만들고 다이얼로그로 변경하는 방법 1) 기존 Activity를 만든다.
2) AndroidManifest.xml에 Activity를 등록할때 다음 사항을 추가한다.
android:theme="@android:style/Theme.Dialog"
- <activity
- android:name=".dictionary.FindWord"
- android:theme="@android:style/Theme.Dialog"
- />
Dialog App 예제
파일명: Layout
파일명: AlertDialogSamples.java
case DIALOG_YES_NO_MESSAGE:
case DIALOG_LIST:
case DIALOG_PROGRESS:
case DIALOG_SINGLE_CHOICE:
case DIALOG_MULTIPLE_CHOICE:
case DIALOG_TEXT_ENTRY:
파일명: arrary.xml
파일명: R.String.xml
알람 처리
mToast.show();
Toast.makeText(context, R.string.repeating_received, Toast.LENGTH_SHORT).show(); //여기에다 미디어 플레이 사용하면 소리가 나온다.
//을 알람메니저가 이 onReceive를 호출해 주기때문에 토스트가 표시된 것이다.
프리퍼런스
파일명: PreferencesFromXml
파일명: array.xml
데이터는 아래 위치에 저장된다.
안드로이드 AVD SDcard Mount 방법
개발을 위해서 Application 을 다운 받아서 설치하려고 했더니..
이게이게 왠일.. SDcard가 없다고 설치가 안된다고 나오더군요.
여기 저기저기 뒤져본 결과...
SDcard 이미지를 만들어서 환경설정에서 AVD 구동시구동시 연결이 되게 하는 방법이 있더군요.
일단 SDcard 파일을파일을 만들어야 합니다.
만드는 방법은...
Android SDK 를 설치를 했다면했다면 SDK설치폴더\tools\ 에 보시면 mksdcard.exe 가 있습니다.
명령프롬프트로 해당 경로로 가셔서 아래와 같이 실행을 합니다.
mksdcard.exe -l sdcard 128M sdcard.iso
실행을 한 후 해당 폴더에 sdcard.iso 파일이파일이 생성되어 있을 겁니다.
이제 이 SDcard 파일을 AVD와AVD와 연결하는게 남았습니다.
이클립스 메뉴에서 [Run] - [Run Configuration...]Configuration...] 아래와 같이 선택합니다.
위와 같이 메뉴를 클릭하면 아래와 같이 설정창이 뜹니다.
Additional Emulator Command Line Options 에
-sdcard SDcard파일 경로 를 입력합니다.
여기까지 하고 Run 하시면 SDcard가 있다고 나옵니다.
끝~
자료 보관할 내용.
* |
* Copyright (C) 2009 The Android Open Source Project |
* |
* Licensed under the Apache License, Version 2.0 (the "License"); |
* you may not use this file except in compliance with the License. |
* You may obtain a copy of the License at |
* |
* http://www.apache.org/licenses/LICENSE-2.0 |
* |
* Unless required by applicable law or agreed to in writing, software |
* distributed under the License is distributed on an "AS IS" BASIS, |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* See the License for the specific language governing permissions and |
* limitations under the License. |
*/ |
package com.example.android.wiktionary; |
import com.example.android.wiktionary.SimpleWikiHelper.ApiException; |
import com.example.android.wiktionary.SimpleWikiHelper.ParseException; |
import android.app.PendingIntent; |
import android.app.Service; |
import android.appwidget.AppWidgetManager; |
import android.appwidget.AppWidgetProvider; |
import android.content.ComponentName; |
import android.content.Context; |
import android.content.Intent; |
import android.content.res.Resources; |
import android.net.Uri; |
import android.os.IBinder; |
import android.text.format.Time; |
import android.util.Log; |
import android.widget.RemoteViews; |
import java.util.regex.Matcher; |
import java.util.regex.Pattern; |
/** |
* Define a simple widget that shows the Wiktionary "Word of the day." To build |
* an update we spawn a background {@link Service} to perform the API queries. |
*/ |
public class WordWidget extends AppWidgetProvider { |
/** |
* Regular expression that splits "Word of the day" entry into word |
* name, word type, and the first description bullet point. |
*/ |
public static final String WOTD_PATTERN = |
"(?s)\\{\\{wotd\\|(.+?)\\|(.+?)\\|([^#\\|]+).*?\\}\\}"; |
@Override |
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { |
Log.d("WordWidget.UpdateService", "onUpdate()"); |
// To prevent any ANR timeouts, we perform the update in a service |
context.startService(new Intent(context, UpdateService.class)); |
} |
public static class UpdateService extends Service { |
@Override |
public void onStart(Intent intent, int startId) { |
Log.d("WordWidget.UpdateService", "onStart()"); |
// Build the widget update for today |
RemoteViews updateViews = buildUpdate(this); |
Log.d("WordWidget.UpdateService", "update built"); |
// Push update for this widget to the home screen |
ComponentName thisWidget = new ComponentName(this, WordWidget.class); |
AppWidgetManager manager = AppWidgetManager.getInstance(this); |
manager.updateAppWidget(thisWidget, updateViews); |
Log.d("WordWidget.UpdateService", "widget updated"); |
} |
@Override |
public IBinder onBind(Intent intent) { |
return null; |
} |
/** |
* Build a widget update to show the current Wiktionary |
* "Word of the day." Will block until the online API returns. |
*/ |
public RemoteViews buildUpdate(Context context) { |
// Pick out month names from resources |
Resources res = context.getResources(); |
String[] monthNames = res.getStringArray(R.array.month_names); |
// Find current month and day |
Time today = new Time(); |
today.setToNow(); |
// Build the page title for today, such as "March 21" |
String pageName = res.getString(R.string.template_wotd_title, |
monthNames[today.month], today.monthDay); |
String pageContent = null; |
try { |
// Try querying the Wiktionary API for today's word |
SimpleWikiHelper.prepareUserAgent(context); |
pageContent = SimpleWikiHelper.getPageContent(pageName, false); |
} catch (ApiException e) { |
Log.e("WordWidget", "Couldn't contact API", e); |
} catch (ParseException e) { |
Log.e("WordWidget", "Couldn't parse API response", e); |
} |
RemoteViews views = null; |
Matcher matcher = null; |
Prefs prefs = new Prefs(this); |
if (pageContent == null) { |
// could not get content, use cache |
// could be null |
pageContent = prefs.getPageContent(); |
} |
if (pageContent != null) { |
// we have page content |
// is it valid? |
matcher = Pattern.compile(WOTD_PATTERN).matcher(pageContent); |
} |
if (matcher != null && matcher.find()) { |
// valid content, cache it |
// ensure that latest valid content is |
// always cached in case of failures |
prefs.setPageContent(pageContent); |
// Build an update that holds the updated widget contents |
views = new RemoteViews(context.getPackageName(), R.layout.widget_word); |
String wordTitle = matcher.group(1); |
views.setTextViewText(R.id.word_title, wordTitle); |
views.setTextViewText(R.id.word_type, matcher.group(2)); |
views.setTextViewText(R.id.definition, matcher.group(3).trim()); |
// When user clicks on widget, launch to Wiktionary definition page |
String definePage = String.format("%s://%s/%s", ExtendedWikiHelper.WIKI_AUTHORITY, |
ExtendedWikiHelper.WIKI_LOOKUP_HOST, wordTitle); |
Intent defineIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(definePage)); |
PendingIntent pendingIntent = PendingIntent.getActivity(context, |
0 /* no requestCode */, defineIntent, 0 /* no flags */); |
views.setOnClickPendingIntent(R.id.widget, pendingIntent); |
} else { |
// Didn't find word of day, so show error message |
views = new RemoteViews(context.getPackageName(), R.layout.widget_message); |
views.setTextViewText(R.id.message, context.getString(R.string.widget_error)); |
} |
return views; |
} |
} |
} |
안드로이드 위젯에서 Activity 호출하기.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout01"
android:layout_height="200dp"
android:background="@drawable/background"
android:layout_width="160dp"
android:orientation="horizontal">
<Button
android:text="@+id/Button01"
android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<TextView
android:id="@+id/widget_textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textColor="@android:color/black"
android:text="17:12:34 PM"
android:textSize="8pt"
/>
호출 받을 Activity만들기
import android.os.Bundle;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO Auto-generated method stub
}
위젯의 배경 이미지 만들기 /res/drawable/background.png
위젯의 레이아웃 만들기 . layout/appwidgetmain.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout01"
android:layout_height="200dp"
android:background="@drawable/background"
android:layout_width="160dp"
android:orientation="horizontal">
<Button
android:text="@+id/Button01"
android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<TextView
android:id="@+id/widget_textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textColor="@android:color/black"
android:text="17:12:34 PM"
android:textSize="8pt"
/>
AppWidgetProvider를 상속 받은 위젯 메인 페이지 만들기.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.RemoteViews;
{
@Override
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds )
{
RemoteViews remoteViews;
ComponentName watchWidget;
DateFormat format = SimpleDateFormat.getTimeInstance( SimpleDateFormat.MEDIUM, Locale.getDefault() );
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setComponent(new ComponentName("com.sh.watchwidget", "com.sh.watchwidget.MyActvity"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
remoteViews = new RemoteViews( context.getPackageName(), R.layout.appwidgetmain );
watchWidget = new ComponentName( context, WatchWidget.class );
remoteViews.setTextViewText( R.id.widget_textview, "Time = " + format.format( new Date()));
remoteViews.setOnClickPendingIntent(R.id.Button01, pendingIntent);
appWidgetManager.updateAppWidget( watchWidget, remoteViews );
}
}
appwidget-provider xml 파일 만들기
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dp"
android:initialLayout="@layout/appwidgetmain"
android:updatePeriodMillis="1000"
android:minHeight="144dp"/>
AndroidManifest.xml 파일에 application 추가하기
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sh.watchwidget"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<receiver android:name=".WatchWidget" android:label="@string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/watch_widget_provider" />
</receiver>
<activity android:name="MyActvity"></activity>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
결과 화면
소스를 보면 간단하지만 2일동안 삽질하여 만들 소스입니다.
아래는 아카이브 파일입니다.
How to make a simple Android widget
Yesterday I made my first Android widget. A very simple widget, just to try it out. It can show the time. No more, no less. I will here show you how to get started on widgets. I’ll start from scratch, so you actually don’t need any knowledge on Android development. Well, of course you need to have the SDK, and Eclipse installed and ready.
I used the 1.5 SDK, but it will probably work on newer SDK’s too.
I will show you how to do it in 6 easy steps.
1. Create a new Android project
Fire up Eclipse, and click File -> New -> Android project
Type in a name for you project, eg. WatchWidget. Select the target, 1.5 in my case. I guess that there could be differences, so if you are not experienced in Android development, I suggest that you use 1.5 too.
Then we need an application name, which is the name that will show up on your phone. And last but not least, a package name.
Uncheck “Create activity”, as we don’t want any activities in this sample.
Click Finish to create the project. Now you have a structure that looks like this:
2. Create the Java class
Right-click com.kasperholtze.watchwidget (or whatever you used for package name), and select New -> Class:
Give the class a name, i.e. WatchWidget. Then we need to extend the AppWidgetProvider, so type in android.appwidget.AppWidgetProvider as superclass, or browse for it.
Click Finish, and Eclipse will generate the following code:
import android.appwidget.AppWidgetProvider;
public class WatchWidget extends AppWidgetProvider {
}
3. Create the Java code
Now it’s time to create our Java code, for updating the widget. Type in the following code:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import com.kasperholtze.watchwidget.R;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.widget.RemoteViews;
public class WatchWidget extends AppWidgetProvider
{
@Override
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds )
{
RemoteViews remoteViews;
ComponentName watchWidget;
DateFormat format = SimpleDateFormat.getTimeInstance( SimpleDateFormat.MEDIUM, Locale.getDefault() );
remoteViews = new RemoteViews( context.getPackageName(), R.layout.main );
watchWidget = new ComponentName( context, WatchWidget.class );
remoteViews.setTextViewText( R.id.widget_textview, "Time = " + format.format( new Date()));
appWidgetManager.updateAppWidget( watchWidget, remoteViews );
}
}
The only method we use in this class, is onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds ), which we override from the AppWidgetProvider class.
First we create three objects. remoteViews, watchWidget and format. remoteViews is a reference to the main view, which we will create in a moment. watchWidget is a reference to our class, and format is the date format used to show the time.
Then we initialize the remoteViews and watchWidget. You will get an error one the line remoteViews.setTextViewText(), which is where we actually update the text on our widget, stating that R.id is not found, but that’s all right for now. We will create that one in a moment too.
appWidgetManager.updateAppWidget sets the RemoteViews that should be used for our widget.
4. Edit the view for our widget, main.xml
Using the UI designer takes some trying, testing and failing. If you have not tried this yet, you should try playing around with it. It takes some time to get the feeling of it.
My main.xml looks like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout01"
android:layout_height="200dp"
android:background="@drawable/background"
android:layout_width="160dp"
android:orientation="horizontal">
<TextView
android:id="@+id/widget_textview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical|center_horizontal"
android:textColor="@android:color/black"
android:text="17:12:34 PM"
android:textSize="8pt"
/>
</LinearLayout>
It contains a LinearLayout with a TextView inside. The important thing is the id of out TextView, which we used earlier in the WatchWidget class.
I used a standard widget background, which you can download at http://developer.android.com/guide/practices/ui_guidelines/widget_design.html. You can also grab it here:
Save it in the project, at res/drawable/background.png
5. Edit AndroidManifest.xml
The next thing is to edit the AndroidManifest.xml, which defines the application. We need to add an intent-filter, meta-data that defines which xml file we use for defining the widget provider, and name and other details of the application.
Here it goes…
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kasperholtze.watchwidget"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<receiver android:name=".WatchWidget" android:label="@string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/watch_widget_provider" />
</receiver>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
6. Create widget provider
The last thing we have to do, before the application is ready to run, is to create a XML file, defining the widget provider. Create a new folder under res, called xml, and save the file as res/xml/watch_widget_provider.xml.
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dp"
android:initialLayout="@layout/main"
android:updatePeriodMillis="1000"
android:minHeight="144dp"/>
Here we set the minimum size that the widget needs to be added to a home screen. And then we set the updatePeriodMillis. updatePeriodMillis defines how often we wish to call the onUpdate method that we created earlier in the Java class.
That’s it! Connect your phone, or fire up a virtual device, and try it out
Using Google Maps in Android
Creating the Project
Using Eclipse, create a new Android project and name GoogleMaps as shown in Figure 1.
Obtaining a Maps API key
Beginning with the Android SDK release v1.0, you need to apply for a free Google Maps API key before you can integrate Google Maps into your Android application. To apply for a key, you need to follow the series of steps outlined below. You can also refer to Google's detailed documentation on the process at http://code.google.com/android/toolbox/apis/mapkey.html.
First, if you are testing the application on the Android emulator, locate the SDK debug certificate located in the default folder of "C:\Documents and Settings\<username>\Local Settings\Application Data\Android"
. The filename of the debug keystore is debug.keystore
. For deploying to a real Android device, substitute the debug.keystore
file with your own keystore file. In a future article I will discuss how you can generate your own keystore file.
For simplicity, copy this file (debug.keystore
) to a folder in C:\
(for example, create a folder called "C:\Android
").
Using the debug keystore, you need to extract its MD5 fingerprint using the Keytool.exe
application included with your JDK installation. This fingerprint is needed to apply for the free Google Maps key. You can usually find the Keytool.exe
from the "C:\Program Files\Java\<JDK_version_number>\bin
" folder.
Issue the following command (see also Figure 2) to extract the MD5 fingerprint.
keytool.exe -list -alias androiddebugkey -keystore "C:\android\debug.keystore" -storepass
android -keypass android
Copy the MD5 certificate fingerprint and navigate your web browser to: http://code.google.com/android/maps-api-signup.html. Follow the instructions on the page to complete the application and obtain the Google Maps key.
To use the Google Maps in your Android application, you need to modify your AndroidManifest.xml
file by adding the <uses-library>
element together with the INTERNET
permission:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.learn2develop.GoogleMaps" android:versionCode="1" android:versionName="1.0.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <uses-library android:name="com.google.android.maps" /> <activity android:name=".MapsActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET" /> </manifest> </xml>
Displaying the Map
To display the Google Maps in your Android application, modify the main.xml
file located in the res/layout
folder. You shall use the <com.google.android.maps.MapView>
element to display the Google Maps in your activity. In addition, let's use the <RelativeLayout>
element to position the map within the activity:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.google.android.maps.MapView android:id="@+id/mapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey="0l4sCTTyRmXTNo7k8DREHvEaLar2UmHGwnhZVHQ" /> </RelativeLayout>
Notice from above that I have used the Google Maps key that I obtained earlier and put it into the apiKey
attribute.
In the MapsActivity.java
file, modify the class to extend from the MapActivity
class, instead of the normal Activity
class:
package net.learn2develop.GoogleMaps; import com.google.android.maps.MapActivity; import com.google.android.maps.MapView; import android.os.Bundle; public class MapsActivity extends MapActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected boolean isRouteDisplayed() { return false; } }
Observe that if your class extends the MapActivity
class, you need to override the isRouteDisplayed()
method. You can simply do so by setting the method to return false.
That's it! That's all you need to do to display the Google Maps in your application. Press F11
in Eclipse to deploy the application onto an Android emulator. Figure 3 shows the Google map in all its glory.
At this juncture, take note of a few troubleshooting details. If your program does not run (i.e. it crashes), then it is likely you forgot to put the following statement in your AndroidManifest.xml
file:
<uses-library android:name="com.google.android.maps" />
If your application manages to load but you cannot see the map (all you see is a grid), then it is very likely you do not have a valid Map key, or that you did not specify the INTERNET
permission:
<uses-permission android:name="android.permission.INTERNET" />
Displaying the Zoom View
The previous section showed how you can display the Google Maps in your Android device. You can drag the map to any desired location and it will be updated on the fly. However, observe that there is no way to zoom in or out from a particular location. Thus, in this section, you will learn how you can let users zoom into or out of the map.
First, add a <LinearLayout>
element to the main.xml
file as shown below:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.google.android.maps.MapView android:id="@+id/mapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey="0l4sCTTyRmXTNo7k8DREHvEaLar2UmHGwnhZVHQ" /> <LinearLayout android:id="@+id/zoom" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" /> </RelativeLayout>
You will use the <LinearLayout>
element to hold the two zoom controls in Google Maps (you will see this shortly).
In the MapsActivity.java
file, add the following imports:
import com.google.android.maps.MapView.LayoutParams; import android.view.View; import android.widget.LinearLayout;
and add the following code after the line setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapView); LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom); View zoomView = mapView.getZoomControls(); zoomLayout.addView(zoomView, new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); mapView.displayZoomControls(true);
The complete MapsActivity.java
file is given below:
package net.learn2develop.GoogleMaps; import com.google.android.maps.MapActivity; import com.google.android.maps.MapView; import com.google.android.maps.MapView.LayoutParams; import android.os.Bundle; import android.view.View; import android.widget.LinearLayout; public class MapsActivity extends MapActivity { MapView mapView; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mapView = (MapView) findViewById(R.id.mapView); LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom); View zoomView = mapView.getZoomControls(); zoomLayout.addView(zoomView, new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); mapView.displayZoomControls(true); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } }
Basically, you obtain the MapView
instance on the activity, obtain its zoom controls and then add it to the LinearLayout
element you added to the activity earlier on. In the above case, the zoom control will be displayed at the bottom of the screen. When you now press F11
in Eclipse, you will see the zoom controls when you touch the map (see Figure 4).
Using the zoom control, you can zoom in or out of a location by simply touching the "+ or "-" buttons on the screen.
Alternatively, you can also programmatically zoom in or out of the map using the zoomIn()
and zoomOut()
methods from the MapController
class:
package net.learn2develop.GoogleMaps; //... import android.os.Bundle; import android.view.KeyEvent; public class MapsActivity extends MapActivity { MapView mapView; public boolean onKeyDown(int keyCode, KeyEvent event) { MapController mc = mapView.getController(); switch (keyCode) { case KeyEvent.KEYCODE_3: mc.zoomIn(); break; case KeyEvent.KEYCODE_1: mc.zoomOut(); break; } return super.onKeyDown(keyCode, event); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { //... } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } }
In the above code, when the user presses the number 3 on the keyboard the map will zoom in into the next level. Pressing number 1 will zoom out one level.
Changing Views of the Map
By default, the Google Maps displays in the map mode. If you wish to display the map in satellite view, you can use the setSatellite()
method of the MapView
class, like this:
mapView.setSatellite(true);
You can also display the map in street view, using the setStreetView()
method:
mapView.setStreetView(true);
Figure 5 shows the Google Maps displayed in satellite and street views, respectively.
Displaying a Particular Location
Be default, the Google Maps displays the map of the United States when it is first loaded. However, you can also set the Google Maps to display a particular location. In this case, you can use the animateTo()
method of the MapController
class.
The following code shows how this is done:
package net.learn2develop.GoogleMaps; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; import com.google.android.maps.MapView.LayoutParams; import android.os.Bundle; import android.view.View; import android.widget.LinearLayout; public class MapsActivity extends MapActivity { MapView mapView; MapController mc; GeoPoint p; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mapView = (MapView) findViewById(R.id.mapView); LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom); View zoomView = mapView.getZoomControls(); zoomLayout.addView(zoomView, new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); mapView.displayZoomControls(true); mc = mapView.getController(); String coordinates[] = {"1.352566007", "103.78921587"}; double lat = Double.parseDouble(coordinates[0]); double lng = Double.parseDouble(coordinates[1]); p = new GeoPoint( (int) (lat * 1E6), (int) (lng * 1E6)); mc.animateTo(p); mc.setZoom(17); mapView.invalidate(); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } }
In the above code, you first obtain a controller from the MapView
instance and assign it to a MapController
object (mc
). You use a GeoPoint
object to represent a geographical location. Note that for this class the latitude and longitude of a location are represented in micro degrees. This means that they are stored as integer values. For a latitude value of 40.747778, you need to multiply it by 1e6 to obtain 40747778.
To navigate the map to a particular location, you can use the animateTo()
method of the MapController
class (an instance which is obtained from the MapView object). The setZoom()
method allows you to specify the zoom level in which the map is displayed. Figure 6 shows the Google Maps displaying the map of Singapore.
Adding Markers
Very often, you may wish to add markers to the map to indicate places of interests. Let's see how you can do this in Android. First, create a GIF image containing a pushpin (see Figure 7) and copy it into the res/drawable
folder of the project. For best effect, you should make the background of the image transparent so that it does not block off parts of the map when the image is added to the map.
To add a marker to the map, you first need to define a class that extends the Overlay
class:
package net.learn2develop.GoogleMaps; import java.util.List; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import com.google.android.maps.MapView.LayoutParams; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Point; import android.os.Bundle; import android.view.View; import android.widget.LinearLayout; public class MapsActivity extends MapActivity { MapView mapView; MapController mc; GeoPoint p; class MapOverlay extends com.google.android.maps.Overlay { @Override public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) { super.draw(canvas, mapView, shadow); //---translate the GeoPoint to screen pixels--- Point screenPts = new Point(); mapView.getProjection().toPixels(p, screenPts); //---add the marker--- Bitmap bmp = BitmapFactory.decodeResource( getResources(), R.drawable.pushpin); canvas.drawBitmap(bmp, screenPts.x, screenPts.y-50, null); return true; } } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { //... } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } }
In the MapOverlay
class that you have defined, override the draw()
method so that you can draw the pushpin image on the map. In particular, note that you need to translate the geographical location (represented by a GeoPoint
object, p) into screen coordinates.
As you want the pointed tip of the push pin to indicate the position of the location, you would need to deduct the height of the image (which is 50 pixels) from the y-coordinate of the point (see Figure 8) and draw the image at that location.
To add the marker, create an instance of the MapOverlap
class and add it to the list of overlays available on the MapView
object:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //... mc.animateTo(p); mc.setZoom(17); //---Add a location marker--- MapOverlay mapOverlay = new MapOverlay(); List<Overlay> listOfOverlays = mapView.getOverlays(); listOfOverlays.clear(); listOfOverlays.add(mapOverlay); mapView.invalidate(); }
Figure 9 shows how the pushpin looks like when added to the map.
Getting the Location that was touched
After using Google Maps for a while, you may wish to know the latitude and longitude of a location corresponding to the position on the screen that you have just touched. Knowing this information is very useful as you can find out the address of a location, a process known as Geocoding (you will see how this is done in the next section).
If you have added an overlay to the map, you can override the onTouchEvent() method within the Overlay
class. This method is fired every time the user touches the map. This method has two parameters - MotionEvent
and MapView
. Using the MotionEvent
parameter, you can know if the user has lifted his finger from the screen using the getAction()
method. In the following code, if the user has touched and then lifted his finger, you will display the latitude and longitude of the location touched:
class MapOverlay extends com.google.android.maps.Overlay { @Override public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) { //... } @Override public boolean onTouchEvent(MotionEvent event, MapView mapView) { //---when user lifts his finger--- if (event.getAction() == 1) { GeoPoint p = mapView.getProjection().fromPixels( (int) event.getX(), (int) event.getY()); Toast.makeText(getBaseContext(), p.getLatitudeE6() / 1E6 + "," + p.getLongitudeE6() /1E6 , Toast.LENGTH_SHORT).show(); } return false; } }
Figure 10 shows this in action.
Geocoding and Reverse Geocoding
If you know the latitude and longitude of a location, you can find out its address using a process known as Geocoding. Google Maps in Android supports this via the Geocoder
class. The following code shows how you can find out the address of a location you have just touched using the getFromLocation()
method:
class MapOverlay extends com.google.android.maps.Overlay { @Override public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) { //... } @Override public boolean onTouchEvent(MotionEvent event, MapView mapView) { //---when user lifts his finger--- if (event.getAction() == 1) { GeoPoint p = mapView.getProjection().fromPixels( (int) event.getX(), (int) event.getY()); Geocoder geoCoder = new Geocoder( getBaseContext(), Locale.getDefault()); try { List<Address> addresses = geoCoder.getFromLocation( p.getLatitudeE6() / 1E6, p.getLongitudeE6() / 1E6, 1); String add = ""; if (addresses.size() > 0) { for (int i=0; i<addresses.get(0).getMaxAddressLineIndex(); i++) add += addresses.get(0).getAddressLine(i) + "\n"; } Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } return true; } else return false; } }
Figure 11 shows the above code in action.
If you know the address of a location but want to know its latitude and longitude, you can do so via reverse-Geocoding. Again, you can use the Geocoder
class for this purpose. The following code shows how you can find the exact location of the Empire State Building by using the getFromLocationName()
method:
Geocoder geoCoder = new Geocoder(this, Locale.getDefault()); try { List<Address> addresses = geoCoder.getFromLocationName( "empire state building", 5); String add = ""; if (addresses.size() > 0) { p = new GeoPoint( (int) (addresses.get(0).getLatitude() * 1E6), (int) (addresses.get(0).getLongitude() * 1E6)); mc.animateTo(p); mapView.invalidate(); } } catch (IOException e) { e.printStackTrace(); }
Once the location is found, the above code navigates the map to the location. Figure 12 shows the code in action.
Summary
In this article, you have learnt a few tricks for the Google Maps in Android. Using Google Maps, there are many interesting projects you can work on, such as geo-tagging, geo-tracking, etc. If you have cool ideas on building cool location-based services, share with us in the comments box below. Have fun!
A Visual Guide to Android GUI Widgets
For rapid development of your user interfaces try DroidDraw
|
remount 한다.
>adb remount
안드로이드에 있는 host 파일을 받는다.
>adb pull /system/etc/hosts D:\TDPlatform\android_home\backup\
hosts 파일 수정한다.
---------------------------------------
기본적으로 로컬만 등록되어 있음.
127.0.0.1 localhost
---------------------------------------
host 파일을 넣는다.
>adb push D:\TDPlatform\android_home\work\hosts /system/etc/
hosts 파일 수정 확인해보기
>adb -e shell
#cat /system/etc/hosts