5

Một lần mà tôi đã có một prob, các bạn đã thực sự hữu ích. Vì vậy, ở đây tôi lại gặp vấn đề khác mà tôi đã rơi vào ...:/getBoolean (EXTRA_NO_CONNECTIVITY) luôn trả về false

Tôi đang chạy NetworkReceiver tùy chỉnh mở rộng BroadcastReceiver. Tôi muốn phát hiện khi điện thoại có kết nối internet để tôi có thể bắt đầu một dịch vụ bất cứ khi nào có. Tôi đã đọc rất nhiều các chủ đề và tất cả các chủ đề nhiều hay ít nhắc đến đoạn mã sau đó không làm việc cho tôi:

public class NetworkReceiver extends BroadcastReceiver { 

private static final String tag = NetworkReceiver.class.getSimpleName(); 

@Override 
public void onReceive(Context context, Intent intent) { 
    Log.i(tag,"****** NetworkReceiver // onReceive()"); 

    boolean noConnection = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 

    if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 
     Log.i(tag,"****** NetworkReceiver // Network Down?: " + intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)); 
    } 

    // TODO Bug: Never stops the service. Stays always connected! 
    if(noConnection) { 
     Log.i(tag,"****** NetworkReceiver // Stopping Service..."); 
     context.stopService(new Intent(context, FetchService.class)); 
    } else { 
     Log.i(tag,"****** NetworkReceiver // Starting Service!"); 
     context.startService(new Intent(context, FetchService.class)); 
    } 
} 

Tôi có vấn đề là logcat luôn trả NetworkDown?: false và dịch vụ không bao giờ dừng lại (nó khởi động lại mọi lúc). Tôi đã thử nó trên giả lập bằng cách nhấn F8 và tôi cũng đã thử nó trên điện thoại dev của tôi (nó không có SIM, truy cập internet là bởi router wifi của tôi) bằng cách tắt router -> không có truy cập internet được đảm bảo!

My Manifest bao gồm các dòng sau:

... 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

<receiver android:name=".NetworkReceiver"> 
    <intent-filter> 
     <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 
    </intent-filter> 
</receiver> 
... 

Tôi cũng nên lưu ý rằng tôi cũng đã cố gắng <action android:name="android.net.ConnectivityManager.CONNECTIVITY_ACTION" /> trong file manifest của tôi không có thay đổi và rằng khi tôi thay đổi dòng: intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false) để intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true) kết quả luôn đúng - và do đó nó luôn cố gắng ngừng dịch vụ của tôi và không bao giờ bắt đầu.

Tôi nghi ngờ rằng Nội dung bổ sung từ Ý định không được đọc chút nào và đó là lý do tại sao giá trị mặc định là getBooleanExtra() luôn trả về.

PS. Tôi đang sử dụng Android 2.1

Cảm ơn!

Trả lời

3

Tôi không chắc chắn về phần Extras không thể đọc được bên trong BroadcastReceiver, nhưng tôi có thể chỉ cho bạn cách tôi sử dụng BroadcastReceiver cho một mục đích tương tự như mục đích của bạn.

Máy thu của tôi chỉ bắt các thay đổi kết nối, nhưng nó KHÔNG đánh giá tình trạng kết nối. Nó thông báo cho các Service thay vì như trong cả hai trường hợp (kết nối hay không) dịch vụ này sẽ có một cái gì đó để làm. Dịch vụ này có thể được chạy hay không vào thời điểm đó, vì vậy nó sẽ hoặc là được bắt đầu hoặc "hiểu biết" (hãy nhớ rằng you can safely call startService() several times, các cuộc gọi không làm tổ):

public class ConnectivityReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     final Intent intentService = new Intent(context, MyService.class); 
     intentService.putExtra(MyService.INTENT_HANDLE_CONNECTIVITY_CHANGE, ""); 

     context.startService(intentService); 
    } 
} 

Sau đó, trong dịch vụ của tôi, tôi đánh giá kết nối và sau đó hành động phù hợp. Chú ý rằng tôi không đánh giá trạng thái kết nối cùng một cách như bạn làm, và điều này có thể là lý do tại sao đoạn code bên dưới công trình nhưng không phải của bạn (dưới đây chỉ là mã có liên quan):

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    if (intent != null) { 
     final Bundle bundle = intent.getExtras(); 

     // Handle the intent INTENT_HANDLE_CONNECTIVITY_CHANGEif any 
     if ((bundle != null) && (bundle.get(INTENT_HANDLE_CONNECTIVITY_CHANGE) != null)) {   
      handleConnectivity(); 
     } 
    } 

    return START_STICKY; 
} 

private void handleConnectivity() { 
    final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    final NetworkInfo netInfo = cm.getActiveNetworkInfo(); 

    if(netInfo != null && netInfo.isConnected()) { 
     // WE ARE CONNECTED: DO SOMETHING 
    } 
    else { 
     // WE ARE NOT: DO SOMETHING ELSE  
    } 
} 

này hoạt động tốt, dưới Android-7 (2.1).

+0

Tôi biết phương pháp bạn đã sử dụng. Tuy nhiên tôi hơi ngạc nhiên khi nhiều người đề nghị mã tôi đã sử dụng (tôi cũng đọc nó trên một cuốn sách O'reilly mà tôi vừa mua trên Android!) Nếu tôi không thể tìm thấy một giải pháp với phát sóng CONNECTIVITY_ACTION tôi nghĩ rằng tôi sẽ làm theo ví dụ của bạn và thực hiện kiểm tra trong Dịch vụ của tôi với các phương thức của ConnectivityManager. Cảm ơn bạn đã trả lời :) – snoopaki

+0

Bạn được chào đón @snoopaki - thực sự tôi sẽ thích đến với một giải pháp sử dụng phương pháp của bạn, nhưng tôi chỉ không nhìn thấy những gì đang xảy ra và tại sao. – Shlublu

+1

Tôi thực sự đã thay đổi dịch vụ của mình thành IntentService và việc xử lý thay đổi kết nối trong dịch vụ có ý nghĩa hơn. Vì vậy, tôi nên chọn câu trả lời của bạn như là một trong những quyền !! thx :) – snoopaki

2

Không biết về lá cờ NO_CONNECTIVITY lạ, nhưng bạn có thể lấy mạng đang hoạt động từ mục đích:

(NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); 

Bạn có lẽ có thể chỉ cần gọi isConnected() trên đối tượng này.

+1

Thanx cho câu trả lời, tôi sẽ ghi nhớ điều đó. Đối với nhiệm vụ hiện tại, tôi đã sử dụng câu trả lời ở trên và nó hoạt động khá tốt atm :) – snoopaki

+1

Hằng số này không còn được dùng nữa. –