2011-12-27 13 views
0

c2dm frameworkを使用してプッシュメッセージを受信するアプリケーションを実装しました。 新しいメッセージが正常に受信されたときに通知を表示します。受信者(c2dm)が新しいメッセージを受信したときに表示を更新する

ただし、この機能を追加するにはどうすればよいですか。受信機は、新しいメッセージ、それは 実行されている場合は、私の活動を通知してい

私はリスナーパターンを使用しようとしました。レシーバにアクティビティの参照を渡しますが、ビュールートコールはワイルドスレッドの例外から返されます。

これを解決するには、

答えて

1

リスナーを使用します。これは、新しい場所を受け取ったときにアクティビティに通知する受信者のサンプルです。それをカスタマイズ:

import android.location.Location; 

public interface OnNewLocationListener { 
    public abstract void onNewLocationReceived(Location location); 
} 

は受信機:活動の

import java.util.ArrayList; 

import org.mabna.order.utils.Farsi; 
import org.mabna.order.utils.MessageBox; 
import org.mabna.order.utils.Utilities; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.location.GpsStatus; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.view.Gravity; 
import android.widget.Toast; 


public class ReceiverPositioningAlarm extends BroadcastReceiver { 

    public static final String COMMAND = "SENDER"; 
    public static final int SENDER_ACT_DOCUMENT = 0; 
    public static final int SENDER_SRV_POSITIONING = 1; 
    public static final int MIN_TIME_REQUEST = 5 * 1000; 
    public static final int MIN_DISTANCE = 10;// in meters 

    public static final String ACTION_REFRESH_SCHEDULE_ALARM = 
      "org.mabna.order.ACTION_REFRESH_SCHEDULE_ALARM"; 

    private static Location currentLocation; 
    private static Location prevLocation; 
    private static Context _context; 
    private String provider = LocationManager.GPS_PROVIDER; 
    private static Intent _intent; 
    private static LocationManager locationManager; 
    private static LocationListener locationListener = new LocationListener() { 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      try { 
       String strStatus = ""; 
       switch (status) { 
       case GpsStatus.GPS_EVENT_FIRST_FIX: 
        strStatus = "GPS_EVENT_FIRST_FIX"; 
        break; 
       case GpsStatus.GPS_EVENT_SATELLITE_STATUS: 
        strStatus = "GPS_EVENT_SATELLITE_STATUS"; 
        break; 
       case GpsStatus.GPS_EVENT_STARTED: 
        strStatus = "GPS_EVENT_STARTED"; 
        break; 
       case GpsStatus.GPS_EVENT_STOPPED: 
        strStatus = "GPS_EVENT_STOPPED"; 
        break; 

       default: 
        strStatus = String.valueOf(status); 
        break; 
       } 
       Toast.makeText(_context, 
         "Status: " + strStatus, 
         Toast.LENGTH_SHORT).show(); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void onProviderEnabled(String provider) { 
     } 

     @Override 
     public void onProviderDisabled(String provider) { 
     } 

     @Override 
     public void onLocationChanged(Location location) { 
      try { 
       Toast.makeText(_context, 
         "***new location***", 
         Toast.LENGTH_SHORT).show(); 
       gotLocation(location); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }; 

    @Override 
    public void onReceive(final Context context, Intent intent) { 

     Toast.makeText(context, "new request received by receiver", 
       Toast.LENGTH_SHORT).show(); 
     _context = context; 
     _intent = intent; 

     locationManager = (LocationManager) context 
       .getSystemService(Context.LOCATION_SERVICE); 

     if (locationManager.isProviderEnabled(provider)) { 
      locationManager.requestLocationUpdates(provider, MIN_TIME_REQUEST, 
        MIN_DISTANCE, locationListener); 

      Location gotLoc = locationManager.getLastKnownLocation(provider); 
      gotLocation(gotLoc); 
     } else { 

      t.setGravity(Gravity.CENTER, 0, 0); 
      t.show(); 


      Intent settinsIntent = new Intent(
        android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
      settinsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      _context.startActivity(settinsIntent); 
     } 
    } 

    private static void gotLocation(Location location) { 
     prevLocation = currentLocation == null ? 
       null : new Location(currentLocation); 
     currentLocation = location; 

     if (isLocationNew()) { 
      // saveLocation(location); 

      // informing the classes outside of this class that e new point 
      // received 
      OnNewLocationReceived(location); 

      Toast.makeText(_context, "new location saved", Toast.LENGTH_SHORT) 
        .show(); 
      stopLocationListener(); 
     } 
    } 

    private static boolean isLocationNew() { 
     if (currentLocation == null) { 
      return false; 
     } else if (prevLocation == null) { 
      return true; 
     } else if (currentLocation.getTime() == prevLocation.getTime()) { 
      return false; 
     } else { 
      return true; 
     } 
    } 


    public static void stopLocationListener() { 
     locationManager.removeUpdates(locationListener); 
     Toast.makeText(_context, "provider stoped", Toast.LENGTH_SHORT) 
       .show(); 
    } 

    // listener ---------------------------------------------------- 

    static ArrayList<OnNewLocationListener> arrOnNewLocationListener = 
      new ArrayList<OnNewLocationListener>(); 

    // Allows the user to set a OnNewLocationListener outside of this class and 
    // react to the event. 
    // A sample is provided in ActDocument.java in method: startStopTryGetPoint 
    public static void setOnNewLocationListener(
      OnNewLocationListener listener) { 
     arrOnNewLocationListener.add(listener); 
    } 

    public static void clearOnNewLocationListener(
      OnNewLocationListener listener) { 
     arrOnNewLocationListener.remove(listener); 
    } 

    // This function is called after the new point received 
    private static void OnNewLocationReceived(Location location) { 
     // Check if the Listener was set, otherwise we'll get an Exception when 
     // we try to call it 
     if (arrOnNewLocationListener != null) { 
      // Only trigger the event, when we have any listener 

      for (int i = arrOnNewLocationListener.size() - 1; i >= 0; i--) { 
       arrOnNewLocationListener.get(i).onNewLocationReceived(
         location); 
      } 
     } 
    } 
} 

Intent intentToFire = new Intent(
       ReceiverPositioningAlarm.ACTION_REFRESH_SCHEDULE_ALARM); 
     intentToFire.putExtra(ReceiverPositioningAlarm.COMMAND, 
       ReceiverPositioningAlarm.SENDER_ACT_DOCUMENT); 

     sendBroadcast(intentToFire); 

     OnNewLocationListener onNewLocationListener = new OnNewLocationListener() { 
      @Override 
      public void onNewLocationReceived(Location location) { 
       try { 
        // do everything you want 
        ReceiverPositioningAlarm.clearOnNewLocationListener(this); 

       } catch (Exception e) { 
        MessageBox.showException(ActDocument.this, e); 
       } 
      } 
     }; 

     // start listening for new location 
     ReceiverPositioningAlarm.setOnNewLocationListener(
       onNewLocationListener); 
+0

コールバックでUIを変更するとcallfromwrongthreadexceptionがスローされます – Bear

+0

あなたのコードを送信できますか? – breceivemail

0

私は同様の作用を行うために探していた:BroadcastReceiver(C2DMに基づいて、アクティビティのUIのTextViewを更新正確に登録する必要があります)。 callFromWrongThreadExceptionカスタムスレッドでuiを更新しようとしています。

私の解決策は単純でした。わかりやすくするため、breceivernailの答えを使用します。アクティビティのOnNewLocationReceivedメソッドをrunOnUiThread()に変更しました。

 @Override 
     public void OnNewLocationReceived(Location location) { 
      runOnUiThread(new Runnable() { 
       public void run(){ 
        /* update UI here */ 


       } 
      }); 
     }; 

あなたはcallFromWrongThreadException breceivernailの答えを取得している場合は正しく、あなたがあなたのスタックトレース内の間違った場所に呼び出しているかを把握しなければなりません。上記の私のソリューションは、UIの更新で問題が発生した場合に例外を解決します。

関連する問題