2012-05-13 2 views
1

나는 안드로이드 위젯을 사용하기 위해 아주 간단한 코드 만 사용하려고합니다. 나는 도처에서 둘러 보았고 좋은 대답을 찾지 못했습니다.Android Widget이 터치에 응답하지 않습니다.

내가 원했던 (지금은) 위젯을 터치하고 현재 값을 표시 할 때 카운터를 증가시키고 싶습니다. 후

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 

    <receiver 
     android:icon="@drawable/ic_launcher" 
     android:name="com.example.mywidget.WordWidget" 
     android:label="@string/app_name"> 
     <intent-filter> 
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
      <action android:name="UPDATE_NUMBER" /> 
     </intent-filter> 

     <meta-data 
      android:name="android.appwidget.provider" 
      android:resource="@xml/widgetinfo" /> 
    </receiver> 

</application> 

로그는 onReceive을 (표시) 홈 화면에 배치 된 후 즉시 호출되고 :

public class WordWidget extends AppWidgetProvider 
{ 
    Integer touchCounter = 0; 

    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
    { 
     //This is run when a new widget is added or when the update period expires. 
     Log.v("wotd", "Updating " + appWidgetIds.length + " widgets"); 

     for(int x = 0; x < appWidgetIds.length; x++) 
     { 
      Integer thisWidgetId = appWidgetIds[x]; 

      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); 
      remoteViews.setTextViewText(R.id.mainText, touchCounter.toString()); 

      Intent widgetIntent = new Intent(context, WordWidget.class); 
      widgetIntent.setAction("UPDATE_NUMBER"); 

      PendingIntent widgetPendingIntent = PendingIntent.getBroadcast(context, 0, widgetIntent, 0); 

      remoteViews.setOnClickPendingIntent(R.id.widgetLinearLayout, widgetPendingIntent); 
      appWidgetManager.updateAppWidget(thisWidgetId, remoteViews); 
     } 
    } 

    @Override 
    public void onReceive(Context context, Intent intent) 
    { 
     Log.v("wotd", "In onReceive with intent=" + intent.toString()); 
     if (intent.getAction().equals("UPDATE_NUMBER")) 
     { 
      Log.v("wotd", "In UPDATE_NUMBER"); 
      touchCounter++; 
      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); 
      remoteViews.setTextViewText(R.id.mainText, touchCounter.toString()); 
     } else 
     { 
      Log.v("wotd", "In ELSE... going on to super.onReceive()"); 
      super.onReceive(context, intent); 
     } 
    } 
} 

이 내 매니페스트의 일부는 다음과 같습니다

내의 AppWidgetProvider입니다 만져지고 있지만 숫자는 결코 증가하지 않습니다. 위젯이 어떻게 작동하는지 완전히 이해하지는 않지만 onUpdate() 이후에 살해되고 있습니까? 그래서 이렇게하려면 지속적인 저장 장치를 사용해야할까요?

또한 현재 다른 위젯을 추가하면 둘 다 동일한 값을 표시하고 하나만 터치해도 증가합니다. 각 위젯이 자신의 카운터를 가질 수있는 방법이 있습니까?

감사합니다.

답변

11

실제로 질문에 답변하셨습니다. 그러나 몇 가지를 명확히 해두 자.

A. AppWidgets은 홈 화면에있는 한 살해되지 않습니다. 그러나 그들은 당신의 것이 아닙니다. 그들은 가정 응용 프로그램의 프로세스에서 실행 중입니다. 더 구체적으로보기가 가정용 응용 프로그램의 프로세스에서 실행되고 있기 때문에 이것이 위젯을 보는 이유입니다. 그러나 예상 한대로 작동하지 않으므로 View 대신 RemoteView를 사용하여 업데이트합니다 .

B. 다른 한편, AppWidgetProviders (귀하의 경우 WordWidget 클래스)는 onReceive 메소드가 완료 되 자마자 파괴됩니다. onReceive 메서드가 호출 될 때마다이 변수의 모든 변수가 다시 초기화됩니다. 이것이 귀하의 전화 번호가 결코 증가하지 않는 이유입니다. AppWidgetProvider의 목적은 위젯의 RemoteView를 업데이트하고 응용 프로그램에 등록 된 브로드 캐스트가 도착했음을 알리는 것입니다.

C. AppWidgetProvider의 onUpdate 메소드는 업데이트해야하는 위젯 ID가있는 Array를 제공합니다. 이것은 위젯 인스턴스의 수와 ID를 얻는 데 사용할 수있는 유일한 코드 포인트입니다. RemoteViews 덕분에 위젯의 뷰 (예 : TextView에서 카운터 값을 읽을 수 없음)에서 유용한 값을 얻을 수있는 방법이 없으므로 제공된 정보를 사용해야합니다. DO 유지 위젯 당 카운터 값 신분증. 다음 onUpdate가 호출되면 저장 장치에서 값을 읽은 다음 값을 늘리고 새 값으로 위젯을 업데이트 한 다음 새 값을 다시 저장합니다.

D. 위젯이 시간을 할애 할 때 (네트워킹 같은) 많은 일을해야하거나 느리게해야한다면,이를 위해 서비스를 고려해야합니다. 그러나 귀하의 경우 (숫자를 늘리기 위해) 영구 저장소 또는 다른 곳에 카운터를 유지하는 한 귀하의 접근 방식은 괜찮습니다.

마지막으로 나는 당신의 onReceive 오버라이드에서 "UPDATE_NUMBER"액션을받지 못했을 때만 "super.onReceive"라고 부르는 것을 발견했습니다. 좋은 이유가 없다면 (다른 이야기이기도합니다) 항상 super.onReceive를 오버라이드의 첫 번째 또는 마지막 명령으로 호출하십시오.

희망이 있습니다.

+0

굉장히 고마워요!나는 블로그 게시물을 읽는 것보다 더 많은 것을 배웠다. onReceive() 메서드의 첫 번째 또는 마지막 명령으로 super.onReceive()를 호출하는 것의 차이점은 무엇입니까? 저는 항상 슈퍼에 관한 질문을했습니다. – Sandy

+2

사실 그것은 당신이하는 일에 달려 있습니다. 예를 들어 return (; return을 호출하여)을 끝내고 싶다면 중간에 어딘가에 메소드를 넣고 싶으면 super (먼저 return 호출 전에)를 호출해야합니다. 그렇지 않으면 last를 호출해야합니다. 그러나 안드로이드에는 super.onDestroy를 먼저 호출해야하는 다른 메소드가 있습니다 (잘 기억한다면 Activity의 onDestroy). 내 응용 프로그램 위젯에서 마지막 명령으로 super.onReceive를 호출하고 있습니다 ... – Christos

+0

onReceive()에서 임의의 값과 같도록 touchCounter를 수정했습니다 (touchCounter = new Random(). nextInt (100);) onUpdate()에서 TextView가 수정되었지만 여전히 값을 변경하지 않은 경우 주석 처리했습니다. 나는 다른 것을 놓치고 있습니까? – Sandy