달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
728x90
반응형
앱위젯만들기 - 배터리 표시기

 

복사 http://blog.naver.com/hojoon108/80143757040

1. 코드 작성시...

앱위젯 코드 작성시 액티비티로 해도 되고 아니어도 된다.

앱위젯은 방송수신자이므로 BR만으로 만들수 있고, 이렇게 만들면 메인메뉴에는 나타나지 않고 홈화면의 팝업메뉴에서만 사용할 수 있다.

2. 시작은 메니페스트에 등록하는 것부터..

앱위젯은 BR이므로 메니페스트에 BR을 등록하여야 한다.

   1:  <receiver android:name=".ShowBattery" android:label="배터리">
   2:    <intent-filter>
   3:      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
   4:    </intent-filter>
   5:    <meta-data android:name="android.appwidget.provider" android:resource="@xml/batteryinfo" />
   6:  </receiver>

클래스 이름은 ShowBattery / label은 호스트 팝업메뉴에 나타난다.

갱신신호를 받아야 하므로 인텐트 필터에 APPWIDGET_UPDATE 신호를 수신한다고 선언해야 한다. 나머지 액션은 호스트가 전달시점을 분명히 알기 때문에 인텐트 필터에 따로 선언하지 않아도 관리자가 알아서 보내준다.

meta-data 태그를 통해 앱위젯의 추가적인 속성을 지정한다.

이름을 android.appwidget.provider로 했으므로 앱위젯 속성을 가진다.

resource에 구체적인 속성을 정의하는 xml문서의 이름을 적어준다. xml 문서의 내용대로 AppWidgetProviderInfo 객체가 생성되며, 호스트는 이 정보를 보고 크기, 갱신주기를 결정

3. batteryinfo.xml

<?xml version="1.0" encoding="utf-8"?>

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"

android:minWidth="72dip"

android:minHeight="72dip"

android:updatePeriodMillis="0"

android:initialLayout="@layout/battery"

>

</appwidget-provider>

갱신주기를 0으로 했으므로 관리자의 갱신신호를 받지 않고 별도의 BR을 설치하여 상태 변경시 즉시 호출되게 만들어야 한다. 크기는 1*1셀 이다. 초기 레이아웃은 battery.xml에 정의된다.


4. battery.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/mainlayout"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<ImageView

android:layout_width="fill_parent"

android:layout_height=fill_parent"

android:gravity="center"

android:src="@drawable/battery"

/>

<TextView

android:id="@+id/gauge"

android:layout_width="fill_parent"

android:layout_height=fill_parent"

android:gravity="center"

android:textsize="20sp"

android:textColor="#000000"

/>

</FrameLayout>

이미지뷰와 텍스트뷰가 중앙정렬로 그려진다. 이미지뷰는 배터리 모양이며 잔량이 백분율 단위로 텍스트뷰에 써지며 서로 겹쳐 있으므로 배터리 그림의 중앙에 텍스트가 써지는 형태가 된다.

5. 메인코드의 작성

메니페스트에 지정한 이름으로 방송수신시 배터리 정보를 조사하고 화면을 갱신하는 코드를 작성한다. 배터리의 잔량을 알려주는 메서드는 따로 없기 때문에 배터리의 상태는 BR을 등록한 후 방송을 수신해야 조사할 수 있다. 배터리 BR을 등록해야 하는데 앱위젯 BR의 onUpdate 에서 배터리 BR등록을 한다면 무한루프에 빠지는 문제가 발생하고, BR 자체가 수신된 방송을 처리하는 동안만 존재하는 임시객체인데 이 안에서 다른 방송 수신을 대기한다는 것도 모순이 된다. 이러한 여러가지 이유로 안드로이드는 BR내에서 다른 BR을 등록하는 것을 허용하지 않는다. 그래서 중간에 다른 서비스코드를 두고 그 코드에서 배터리BR을 등록하는 형태로 코드를 작성해야 한다. 방송처리를 위해 별도의 서비스 객체를 생성했으므로 onDeleted에 서비스 객체를 정리하는 코드도 추가해야 한다. 결과적으로 메인코드에서는 서비스 시작 및 정리만 담당하고 주된 업무는 서비스 코드가 담당한다. 서비스 코드도 메니페스트에 등록해야 한다.

6. ShowBattery.java

public class ShowBattery extends AppWidgetProvider {

public void onUpdate(Context context, AppWidgetManager appWM , int[] appWIDs)

{

Intent intent = new Intent(context , BatteryService.class);

context.StartService(intent);

}

public void onDeleted(Context context)

{

Intent intent = new Intent(context , BatteryService.class);

context.stopService(intent);

}

}

전역자원 할당은 필요치 않으므로 onEnabled, onDisabled는 구현하지 않음

7. BatteryService.java

public class BatteryService extends Service {

public int onStartCommand(Intent intent, int flags, int startId) {

super.onStartCommand(intent, flags, startId);

IntentFilter filter = new IntentFilter();

// 잔량 변화 액션 등록

filter.addAction(Intent.ACTION_BATTERY_CHANGED);

// 배터리 BR 등록

registerReceiver(mBRBattery, filter);

return START_STICKY;

}

public IBinder onBind(Intent arg0) {

return null;

}

public void onDestroy() {

super.onDestroy();

unregisterReceiver(mBRBattery);

}

BroadcastReceiver mBRBattery = new BroadcastReceiver() {

// 방송수신 후 잔량을 출력하는 배터리 BR이 되겠다.

public void onReceive(Context context , Intent intent) {

String action = intent.getAction();

if(action.equals(Intent.ACTION_BATTERY_CHANGED)) {

int sca , level , ratio;

//배터리매니져 정보로 부터 잔량 계산

sca = intent.getIntExtra(BatteryManager.EXTRA_SCALE,100);

level = intent.getIntExtra(BatteryManager.EXTRA_SCALE,0);

ratio = level * 100 / sca;

//리모트뷰를 생성-패키지명, 레이아웃 전달

//레이아웃내의 텍스트뷰의 텍스트 설정

//아직까지 화면에 출력되는게 아니다.

RemoteViews views = nwe RemoteViews(context.getPackageName(),battery);

views.setTextViewText(R.id.gauge,""+ratio+"%");

//위젯메니져가 현재 서비스의 인스탄스를 얻고

AppWidgetManager wm = AppWidgetManager.getInstance(BatteryService.this);

//화면에 등록된 위젯들을 얻고

ComponentName widget = new ComponentName(context, ShowBattery.class);

//그 위젯들에 리모트뷰 객체를 전달해 준다.

// 아래 메서드는 3가지 버젼이 있다. 두번째 인수는 같고

// 첫번째 인수가 특정 인스탄스의 ID

// 또는 ID 배열 또는 컴포넌트 이름

wm.updateAppwidget(widget,views);

}

}

};

}

728x90
반응형
:
Posted by mapagilove