2015-01-16 2 views
3

은 내가 브로드 캐스트 리시버 상속 클래스를 사용하여 네트워크 상태를 확인하는 안드로이드 응용 프로그램을 작성했습니다하지 : 다음과 같이 매니페스트 파일에 등록되어응용 프로그램을 수동으로 닫혀있는 경우 감지 또는

public class NetworkChangeReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(final Context context, final Intent intent) { 
     Log.d("mylog", "NetworkChangeReceiver Hit"); 
    } 
} 

:

<receiver 
    android:name="foo.NetworkChangeReceiver" 
    android:label="NetworkChangeReceiver" > 
    <intent-filter> 
     <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 
     <action android:name="android.net.wifi.WIFI_STATE_CHANGED" /> 
    </intent-filter> 
</receiver> 

연결하거나 연결을 끊을 때마다 인터넷 연결을 처리해야했습니다. 사실 정상적인 상황에서는 완벽하게 작동합니다.

그러나 문제는 응용 프로그램을 최소화하여 응용 프로그램을 최소화 한 다음 응용 프로그램 아이콘을 Recents 버튼 메뉴에서 스 와이프하여 닫으면 문제가 발생하지만 여전히 네트워크 상태 변경 사항을 수신합니다. 때때로 일부 예외가 발생합니다.

심지어 수신기 기능의 모든 코드를 try/catch 블록에 포함 시켰지만 여전히 오류 메시지가 포함 된 축배 메시지가 표시됩니다. 앱을 종료 한 후 며칠 후에도 가끔씩 이런 일이 발생합니다.

수신기 기능의 코드는 여기에 표시된 코드보다 복잡하며 내부 클래스와 변수에 대한 일부 액세스 권한이 있습니다.

+0

"해결책 찾음"이 답변으로 게시되어야 함 –

답변

2

앱은 여전히 ​​받게됩니다 이벤트를 실행하지 않아도됩니다.

옵션 1 :

public class YourActivity extends Activity { 


public static boolean isRunning = false; 

@Overrride 
public void onCreate(Bundle savedInstanceState){ 
isRunning = true; 
    .... 
} 
    //We need receiver to work when app is minimized 
    /* 
     @Override 
     public void onStart() { 
     super.onStart(); 
     isRunning = true; 
     } 


     @Override 
     public void onStop() { 
     super.onStop(); 
     isRunning = false; 
     } 
*/ 

} 

:은 수신기로부터 액세스를 위해이 상태의 확인 활동에 정적 변수를 사용하면 onReceive()에 아무것도하기 전에 활동에 의해 실행 여부를 확인할 수 있습니다 그리고 수신기 :

public class NetworkChangeReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(final Context context, final Intent intent) { 
     Log.d("mylog", "NetworkChangeReceiver Hit"); 
      if(!YourActivity.isRunning) 
       return; 
    } 
} 

옵션 2 다음 ActivityManager

사용 당신은 권한이 필요합니다
public class NetworkChangeReceiver extends BroadcastReceiver { 
@Override 
public void onReceive(final Context context, final Intent intent) { 

    if (isAppForground(context)) 
     return; 

} 

public boolean isAppForground(Context mContext) { 

    ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); 
    List<RunningTaskInfo> tasks = am.getRunningTasks(1); 
    if (!tasks.isEmpty()) { 
     ComponentName topActivity = tasks.get(0).topActivity; 
     if (!topActivity.getPackageName().equals(mContext.getPackageName())) { 
      return false; 
     } 
    } 

    return true; 
} 

} 

: 찾을 수

<uses-permission android:name="android.permission.GET_TASKS" /> 
+0

친애하는 나나, 어느 옵션도 나를 위해 일하지 않습니다. 첫 번째 옵션의 경우 리시버를 최소화해야 사용할 수 있습니다. 그러나 앱이 최소화되면 onStop이 호출됩니다. isRunning 플래그를 검사하면 수신자가 작동하지 않습니다. 내 솔루션은 onStop 대신 onDestroy를 사용할 수 있지만 문제는 모든 상황에서 onDestroy가 호출되지 않는다는 것입니다. 특히 앱이 최근 목록에서 앱 아이콘을 스 와이프하여 닫을 때 문제가 발생합니다. 비슷한 이유로 두 번째 옵션이 내 문제에 적합하지 않습니다. –

+0

여전히 옵션 1을 사용할 수 있습니다. onCreate()에 isRunning 플래그를 설정하고 onStart() 및 onStop()을 주석 처리하기 만하면됩니다. 앱이 최근 목록을 통해 닫히면 isRunning은 false로 재설정됩니다. 나는 내 대답을 업데이트했습니다 –

+0

누가이 답변에 투표했는지 알지 못합니다. 정확히 내가 필요한 것입니다. 나는 옵션 1을 사용했고 매력처럼 작동했습니다. 답변 해주셔서 감사합니다. Up-voted! – wendelbsilva

1

매니페스트에 리시버를 정의하면 앱이 시작되지 않아도 이벤트를 수신합니다.

http://developer.android.com/guide/topics/manifest/receiver-element.html

방송 수신기는 응용 프로그램의 다른 구성 요소가 실행되지 않을 경우에도 시스템에 의해 또는 다른 응용 프로그램에서 방송하는 의도를받을 애플리케이션을 가능하게한다.

는 매니페스트에서 수신기를 정의하지,이 문제를 해결하려면,하지만 onStart에 프로그래밍 방식으로 수행하고 onStop에 다시 등록을 취소. 이 솔루션의 문제점은 앱이 백그라운드에있는 경우 메시지를받지 않는다는 것입니다.

private BroadcastReceiver receiver; 

@Overrride 
public void onStart(){ 

    super.onStart(); 

    IntentFilter filter = new IntentFilter(); 
    filter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); 
    filter.addAction("android.net.wifi.WIFI_STATE_CHANGED"); 

    receiver = new NetworkChangeReceiver(); 
    registerReceiver(receiver, filter); 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
    //don't forget to unregister the receiver again 
    unregisterReceiver(receiver); 
} 

편집 : onDestroy이 응용 프로그램은 닫혀 모든 인스턴스에서 호출되지 않으므로 (예를 들어,이 작업 관리자와 닫혀있는 경우) onCreateonDestroy가 작동하지 않습니다

+0

친애하는 친구, 솔루션에 버그가 있으며 모든 상황에서 onDestroy가 호출되지 않습니다. 예를 들어 최근 아이콘 목록에서 앱 아이콘을 스 와이프하여 앱을 닫은 경우를 예로들 수 있습니다. 이 경우 수신자 등록이 취소되지 않습니다 –

+0

예, 맞습니다. 그에 대한 답변을 업데이트하겠습니다. – tknell

+0

이것은 확실히 가장 우아한 해결책입니다. (더 정확한) – mdelolmo

0

해결 방법 :

나는 내 문제에 대한 완벽한 솔루션을 발견했다. Android service crashes after app is swiped out of the recent apps list의 정답 덕택에, 최근 목록을 통해 앱을 닫을 때 전체 프로세스가 다시 생성되고 모든 정적 변수가 기본값으로 다시 표시되고 onCreate 및 다른 모든 방법은 불리다. 그래서 해결책은 뭔가 같은 :

public static boolean appStarted = false; 
protected void onCreate(Bundle savedInstanceState) { 
    appStarted = true; 
    ... 
} 


public class NetworkChangeReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(final Context context, final Intent intent) { 
     if (!MyActivity.appStarted) 
      return; 
     ... 
    } 
} 

의 핵심은 응용 프로그램의 폐쇄 이벤트가 신뢰할 수 없기 때문에 응용 프로그램이 (닫힐 때 바로 그 때 응용 프로그램의 시작을 추적하고,하지 않는 것입니다 어떤 상황에서 케이

관련 문제