質問

私のアプリには、一連のテキストを受信するとGPSをオンにするブロードキャストレシーバーがあります。 onlocationchangedメソッドでは、共有設定から文字列内のスレッドにGPSデータと値を渡したいと考えています。
ログに書き込みスレッドがあり、文字列内のすべてのGPS値を見ることができますが、共有設定の最後の値は、レシーバークラスの先頭に文字列を初期化した「プリフェネヌム」として表示されます。メインクラスの共有設定からプリフフォネナムを読むのと同じコードがあり、そこで機能しますが、誰もが私が間違っていることを見ることができますか?

public class SmsReceiver extends BroadcastReceiver implements LocationListener
{
     LocationManager lm;
     LocationListener loc;
     public SharedPreferences sharedpreferences;    
     public static final String US = "usersettings";
     public String prefPhoneNum = "prefPhoneNum";

    @Override
    public void onReceive(Context context, Intent intent) 
    {    
        sharedpreferences = context.getSharedPreferences(US, Context.MODE_PRIVATE);
        prefPhoneNum = sharedpreferences.getString("prefPhoneNum" , "");
        lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        loc = new SmsReceiver();

        //---get the SMS message passed in---
        Bundle bundle = intent.getExtras();   
        SmsMessage[] msgs = null;
        String str = ""; 

        if (bundle != null)
        {
            //---retrieve the SMS message received---
            Object[] pdus = (Object[]) bundle.get("pdus");
            msgs = new SmsMessage[pdus.length];            
            for (int i=0; i<msgs.length; i++)
            {
                msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
                str += msgs[i].getMessageBody().toString() + "\n";        
            } 

             Toast.makeText(context, str, Toast.LENGTH_SHORT).show();     //Display SMS

            if ((msgs[0].getMessageBody().toString().equals("Enable")) ||
                    (msgs[0].getMessageBody().toString().equals("enable")))
            {             
                enableGPS();
            }    
            else {  /* Do Nothing*/ }
        }              
    }

    public void enableGPS() {  
      //new CountDownTimer(10000, 1000) {       //10 seconds
        new CountDownTimer(300000, 1000) {      //300 secs = 5 mins
            public void onTick(long millisUntilFinished) 
            {
               lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, loc);  
            }
            public void onFinish() 
            {                   
               lm.removeUpdates(loc);       
            }
       }.start();          
    }    

    @Override
    public void onLocationChanged(Location location) {
      String s = "";
         s += location.getLatitude()  + "\n";
         s += location.getLongitude() + "\n";
         s += location.getAltitude()  + "\n";
         s += location.getAccuracy()  + "\n" + prefPhoneNum;

         Thread cThread = new Thread(new SocketsClient(s));
         cThread.start();
   }

    @Override
    public void onProviderDisabled(String provider) {   }
    @Override
    public void onProviderEnabled(String provider)  {   }
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {   }
}  

これがアプリケーションがシャットしたときのログキャットです -

D/LocationManager( 3912): requestLocationUpdates: provider = gps, listener = accel.working.TrackGPS@4628bce0  
D/GpsLocationProvider(   96): setMinTime 0  
D/GpsLocationProvider(   96): startNavigating  
D/GpsLocationProvider(   96): TTFF: 3227  
D/AndroidRuntime( 3912): Shutting down VM  
W/dalvikvm( 3912): threadid=1: thread exiting with uncaught exception (group=0x400259f8)  
E/AndroidRuntime( 3912): FATAL EXCEPTION: main  
E/AndroidRuntime( 3912): java.lang.NullPointerException  
E/AndroidRuntime( 3912):    at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:146)  
E/AndroidRuntime( 3912):    at accel.working.TrackGPS.onLocationChanged(TrackGPS.java:63)  
E/AndroidRuntime( 3912):    at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:191)  
E/AndroidRuntime( 3912):    at android.location.LocationManager$ListenerTransport.access$000(LocationManager.java:124)  
E/AndroidRuntime( 3912):    at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:140)  
E/AndroidRuntime( 3912):    at android.os.Handler.dispatchMessage(Handler.java:99)  
E/AndroidRuntime( 3912):    at android.os.Looper.loop(Looper.java:144)  
E/AndroidRuntime( 3912):    at android.app.ActivityThread.main(ActivityThread.java:4937)  
E/AndroidRuntime( 3912):    at java.lang.reflect.Method.invokeNative(Native Method)  
E/AndroidRuntime( 3912):    at java.lang.reflect.Method.invoke(Method.java:521)  
E/AndroidRuntime( 3912):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)  
E/AndroidRuntime( 3912):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)  
E/AndroidRuntime( 3912):    at dalvik.system.NativeStart.main(Native Method)  
役に立ちましたか?

解決

あなたは私たちのonreceieve()であまりにも多くのことをしています。ドキュメントから http://developer.android.com/reference/android/content/broadcastreceiver.html#receiverlifecycle :

BroadCastReceiverオブジェクトは、通話の期間中にのみ有効です(コンテキスト、意図)。コードがこの関数から戻ってくると、システムはオブジェクトが終了し、アクティブではなくなっていると見なします。

これには、receive(コンテキスト、意図)実装でできることに重要な影響があります。非同期操作を必要とするものはすべて利用できません。なぜなら、非同期操作を処理するために関数から戻る必要があるからですもはやアクティブではないため、非同期操作が完了する前にシステムは自由にプロセスを殺すことができます。

特に、ダイアログを表示したり、BroadcastReceiver内からサービスにバインドしたりすることはできません。前者の場合、代わりにNotificationManager APIを使用する必要があります。後者の場合、Context.startService()を使用して、サービスにコマンドを送信できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top