티스토리 뷰
UI를 갖지 않는 프래그먼트를 이용하자
이런 프래그먼트를 헤드리스 프래그먼트라고 합니다. 기본 액티비티를 클래스로서
BaseActivity를 만들고 거기에 액티비티의 공통된 처리를 구현하는 경우가 있습니다.
그러한 공통 처리에서 UI이와 연결되지 않는 부분을 헤드리스 프래그먼트로서 구현할 수 있습니다. 여기에서는 네트워크 연결 확인 및 네트워크 연결 변경 감지를 프래그먼트로 구현 해보겠습니다
public class MainActivity extends AppCompatActivity {
private NetworkCheckFragment mFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// NetworkCheckFragment에서 정의한 TAG(문자열)로 프래그먼트가 추가 되었는지 체크합니다.
mFragment = (NetworkCheckFragment) getSupportFragmentManager().findFragmentByTag(NetworkCheckFragment.TAG);
if (mFragment == null) {
mFragment = mFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.add(mFragment, NetworkCheckFragment.TAG)
.commit();
}
}
}
: UI를 갖지 않는 프래그먼트를 갖지 않는 경우 ViewGroup의 레이아웃의 ID는 지정할
필요가 없습니다. 추후 BroadcastReceiver 와 LocalBroadcastManager 설명 하겠습니다.
public class NetworkCheckFragment extends Fragment {
public static final String TAG = NetworkCheckFragment.class.getSimpleName();
public static final String ACTION_CHECK_INTERNET = "ACTION_CHECK_INTERNET";
public static final String KEY_CHECK_INTERNET = "KEY_CHECK_INTERNET";
private IntentFilter mIntentFilter;
public NetworkCheckFragment() {
}
public static NetworkCheckFragment newInstance() {
return new NetworkCheckFragment();
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_CHECK_INTERNET.equals(action)) {
// 네트워크 연결 변경에 따른 공통 처리
boolean isConnected = intent.getBooleanExtra(KEY_CHECK_INTERNET, false);
if (isConnected) {
// 인터넷 연결이 있는 경우
Toast.makeText(context, "인터넷 연결 있음", Toast.LENGTH_SHORT).show();
} else {
// 인터넷 연결이 없는 경우
Toast.makeText(context, "인터넷 연결 없음", Toast.LENGTH_SHORT).show();
}
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
setRetainInstance(true);
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume");
if (mIntentFilter == null) {
mIntentFilter = new IntentFilter(ACTION_CHECK_INTERNET);
}
LocalBroadcastManager.getInstance(getContext()).registerReceiver(mReceiver, mIntentFilter);
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause");
LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mReceiver);
}
public static boolean isInternetConnected(Context context) {
return isWifiConnected(context) || isMobileConnected(context);
}
public static boolean isWifiConnected(Context context) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (info != null && info.isConnected()) {
return true;
}
return false;
}
public static boolean isMobileConnected(Context context) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (info != null && info.isConnected()) {
return true;
}
return false;
}
}
네트워크 변경이 감지되면 MyReceiver에서 LocalBroadcastManager로 통지 합니다.
Intent 를 통해서 NetworkCheckFragment 쪽에서 받아서 처리 할 수 있습니다.
/**
* 네트워크 연결을 확인하는 BroadcastReceiver
*/
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("MyReceiver", "onReceive");
Intent i = new Intent(NetworkCheckFragment.ACTION_CHECK_INTERNET);
i.putExtra(NetworkCheckFragment.KEY_CHECK_INTERNET,
NetworkCheckFragment.isInternetConnected(context));
// 연결 변경 알림
LocalBroadcastManager.getInstance(context).sendBroadcast(i);
}
}
AndroidManifest.xml 잊지 말자
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
</application>
여기서 주의 사항 !!!!
build.gradle 에 targetSdkVersion 버전을 26으로 했을때 브로드캐스트가 동작하니
않는 오류가 있었음... 버전 업데이트 이후 의존성이 깨진듯 한데 추후 해결 방법 확인해서 올려 놓겠습니다. 지금은 꼭 23버전으로 실행해보시길... 물론 귀차니즘이 발동
해서 24 , 25 버전은 테스트 하지 않았습니다.... 어짜피 해결해야 될 상황이기에...
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.geunho.myapplication"
minSdkVersion 21
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support:support-v4:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
'android' 카테고리의 다른 글
7. LocalBroadcastReceiver 를 이해하자 (0) | 2018.05.20 |
---|---|
6. BroadcastReceiver로 브로드캐스트 이벤트를 수신하자 (0) | 2018.05.20 |
4.중첩 프래그먼트를 이용하자 (0) | 2018.05.09 |
3. 프래그먼트를 동적으로 추가 및 삭제하기 (0) | 2018.05.03 |
2.프래그먼트를 이해하자 (0) | 2018.05.03 |