2017-03-10 46 views
0

我有呼叫接收器,我只想在來電時顯示對話框。爲此,我創建了一個全局布爾變量,並試圖在振鈴狀態下將其值更改爲true。但是當呼叫斷開時,代碼總是選擇布爾值的默認值而不是在振鈴狀態下給出的更新值。變量是num。爲什麼它總是給出虛假的價值,儘管它的價值只有在響鈴狀態纔會變得真實。下面是代碼:呼叫接收器中的布爾值不更新

public class phonerece extends BroadcastReceiver{ 
private Boolean num = false; 

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



     if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { 
//some task here 
        } 
     } else if (extraState != null) { 
      if (extraState.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) { 
//task    

      } else if (extraState 
        .equals(TelephonyManager.EXTRA_STATE_IDLE)) { 
         if (num) { 
         phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); 
//call dialog      } 
        } 

       } else if (extraState.equals(TelephonyManager.EXTRA_STATE_RINGING)) { 


          if (checknumber() != null) { 
         Log.e("Nummber", "found"); 
        } else { 
         Log.e("Number", "Not Found"); 
         num = true; 
               } 


       } 


      } 
     } 



    public String checknumber() { 

     String res = null; 
     try { 
      ContentResolver resolver = context.getContentResolver(); 
      Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)); 
      Cursor c = resolver.query(uri, new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null); 

      if (c != null) { // cursor not null means number is found contactsTable 
       if (c.moveToFirst()) { // so now find the contact Name 
        res = c.getString(c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 
       } 
       c.close(); 
      } 
     } catch (Exception ex) { 
     /* Ignore */ 
     } 

     return res; 
    } 
} 

回答

0

你應該使用靜態變量(私有靜態NUM = FALSE)或保存在SharedPreferences您的變量(這是更好),因爲BroadcastReceivers不保存廣播之間。每個廣播都會創建一個新的BroadcastReceiver實例,至少如果通過清單自動註冊的話。

+0

您的共享首選想法更可行。 – Panache

0

(你的代碼片段看起來壞了,num變量缺失的類型?這個答案假定其類型是boolean。)

這聽起來像是一個多線程的問題。 java中的線程可能會緩存變量的值,因爲通過主內存進行同步更加昂貴。您可以通過將相關字段標記爲volatile來強制進行同步。該關鍵字解釋爲here

當一個字段被標記爲volatile時,線程可能不緩存它的值,並且變量的所有修改對所有其他線程都可見。

private volatile boolean num = false; 
+0

使其變得不穩定後,仍然會獲得虛假價值而不是真實價值。 – Panache

+0

@Panache,太糟糕了......:/在調試時,您可以讓調試器監視變量的值,並在值更改(或甚至訪問)時中斷代碼執行。這樣,您可能能夠捕捉到如果,何時和誰更改了值(返回),或者如果它首先被更改 - 可能是錯誤的實例更改了? – hiergiltdiestfu

+0

我是這樣做的......但是值首先被改變爲真,但之後從未被空閒狀態選取。 – Panache