android.os.Build.MODEL 을 확인해 보면 "sdk"라고 나올 경우는 에뮬레이터 환경
기타 제조사등의 정보도 android.os.Build를 확인하면 가능함.
SystemProperty를 통해서 알수 있는 방법도 확인이 필요함.
(SystemProperties는 private 영역으로 접근 불가함.)
하나씩 설명하기 어려우니 작성한 소스를 올린다.
package com.bloodlee;
/**
* MapView를 위한 Sample을 작성합니다.<br>
* 1. 현재 GPS 정보를 조회하여 Map을 그립니다.<br>
* 2. GPS 정보가 변경되면 해당 위치를 다시 그립니다.<br>
* 3. 혠 wjdqh
* @author bloodlee
*/
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import com.bloodlee.R;
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 android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class MapviewSample extends MapActivity implements LocationListener{
MapController mc;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// MapView 생성
MapView mapView = (MapView) findViewById(R.id.mapview);
// MapView 하단에 Zoom 생성
mapView.setBuiltInZoomControls(true);
// LocationManager를 구한다.
LocationManager locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// 현재 시스템의 LocationManager에서 활성화된 Provider를 조회한다.
List<String> providers = locManager.getProviders(true);
for(int i=0; i < providers.size();i++)
Log.i("Providers in LocationManager",providers.get(i));
// Provider의 조건으로 최적의 Provider를 조회한다.
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = locManager.getBestProvider(criteria, true);
Log.i("BestProvider",provider);
// Provider에 저장된 최종 위치 정보를 조회한다.
Location loc = locManager.getLastKnownLocation(provider);
GeoPoint p = null;
// Provider를 통해 현재 위치를 조회한다.
if(loc != null){
int lat = (int)(loc.getLatitude()* 1E6);
int lng = (int)(loc.getLongitude() * 1E6);
p = new GeoPoint(lat, lng);
Log.i("GPS Information","[" + lat + "],[" + lng + "]");
}
else{ // 현재 위치를 조회할 수 없는 경우 기본값(명동)을 설정한다.
Log.i("GeoPoint","Location is null");
p = new GeoPoint(37559978,126985806);
}
Log.i("Address",getAddress(p));
mc = mapView.getController();
mc.animateTo(p);
// Zoom Level을 설정한다. 1 ~ 21까지. 21이면 최대 확대
mc.setZoom(15);
// GPS 정보가 변경을 조회한다. GPS가 변경되면 onLocationChanged 호출
locManager.requestLocationUpdates(provider, 1000L, 500.0f, this);
}
/**
* LocationListener를 통해 GPS 정보가 변경되는 경우 호출
*/
public void onLocationChanged(Location loc) {
if (loc != null) {
int lat = (int)(loc.getLatitude()* 1E6);
int lng = (int)(loc.getLongitude() * 1E6);
GeoPoint p = new GeoPoint(lat, lng);
mc.animateTo(p);
Log.d("onLocationChanged","[" + lat + "],[" + lng + "]");
Log.i("Address",getAddress(p));
}
}
public void onProviderDisabled(String provider) {
// required for interface, not used
}
public void onProviderEnabled(String provider) {
// required for interface, not used
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// required for interface, not used
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
/**
* 취치 정보로 해당 주소 정보를 조회한다.
*/
private String getAddress(GeoPoint p){
// 주소 정보를 조회합니다.
// 한국 주소가 잘 안나오는 것 같다.
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
StringBuilder sb = new StringBuilder();
try{
List<Address> addrList = geocoder.getFromLocation((double)(p.getLatitudeE6() / 1E6),
(double)(p.getLongitudeE6() / 1E6),
10);
if (addrList.size() > 0) {
Address addr = addrList.get(0);
/* 잘 안나옴.
for (int i = 0; i < addr.getMaxAddressLineIndex(); i++)
sb.append(addr.getAddressLine(i)).append(", ");
Log.i("addr.getAddressLine(i))", sb.toString());
sb.append(addr.getAdminArea()).append(", ");
if(addr.getAdminArea() != null)
Log.i("addr.getAdminArea()", addr.getAdminArea());
sb.append(addr.getSubAdminArea()).append(", ");
if(addr.getSubAdminArea() != null)
Log.i("addr.getSubAdminArea()", addr.getSubAdminArea());
sb.append(addr.getPremises()).append(", ");
if(addr.getPremises() != null)
Log.i("addr.getPremises()", addr.getPremises());
*/
sb.append(addr.getFeatureName()).append(", "); // 번지
sb.append(addr.getLocality()).append(", "); // 시, 군
sb.append(addr.getPostalCode()).append(", ");
sb.append(addr.getCountryName());
Log.i("Address", sb.toString());
Toast.makeText(MapviewSample.this, sb.toString(), Toast.LENGTH_LONG).show();
}
}catch(IOException ioe){
Log.e("Exception on getting Geocoder", ioe.getLocalizedMessage());
}
return sb.toString();
}
}
Time을 화면에 그리기 위한 TextView를 정의한다.
4. AppWidgetProvider를 상속한 class 생성
public class TimeWidget extends AppWidgetProvider {
java.text.DateFormat timeformat = SimpleDateFormat.getTimeInstance( SimpleDateFormat.MEDIUM, Locale.getDefault() );
@Override
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds )
{
updateTime( context, appWidgetManager);
}
@Override
public void onReceive(Context context, Intent intent) {
updateTime( context, AppWidgetManager.getInstance(context););
}
public void updateTime( Context context, AppWidgetManager appWidgetManager)
{
RemoteViews remoteViews1;
ComponentName watchWidget;
remoteViews1 = new RemoteViews( context.getPackageName(), R.layout.main );
watchWidget = new ComponentName( context, WatchWidget.class );
remoteViews1.setTextViewText( R.id.widget_timeview, timeformat.format( new Date()));
appWidgetManager.updateAppWidget( watchWidget, remoteViews1 );
}
}
emulator에서 확인해 보니 실제 WIdget이 화면에 설정되면 onReceive() method가 호출되고 업데이트 주기가 되면 onUpdate() method가 호출됨을 확인하였다.
5. Widget 설정하기
이렇게 만들어진 Widget을 어떻게 단말에 설정할까? emulator의 menu > add > widget을 선택하면 설정할 수 있는 widget list가 나온다 그리고 선택하면 된다.
근데 지울때는? 이거땜에 구글링을 했다. Widget을 한 2초 정도 누르고 있으면 하단에 휴지통이 생긴다. 그럼 선택한 widget을 휴지통에 드래그하면 삭제된다.
주의) 삽질하고 알아낸 건데 업데이트 주기는 30분 이상으로 설정되어야 하는 것 같다.