diff --git a/app/build.gradle b/app/build.gradle index 0d91e5c..b7da2eb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,15 +1,15 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 23 - buildToolsVersion "24.0.0 rc1" + compileSdkVersion 24 + buildToolsVersion "24.0.2" defaultConfig { applicationId "com.aspsine.fragmentnavigator.demo" minSdkVersion 11 - targetSdkVersion 23 - versionCode 2 - versionName "2.0" + targetSdkVersion 24 + versionCode 3 + versionName "3.0" } buildTypes { release { @@ -17,12 +17,16 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + repositories { + maven { url "https://jitpack.io" } + } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') - testCompile 'junit:junit:4.12' compile project(':library') - compile 'com.android.support:appcompat-v7:23.3.0' - compile 'com.android.support:support-v4:23.3.0' +// compile 'com.github.Aspsine:FragmentNavigator:1.0.2' + compile 'com.android.support:appcompat-v7:24.2.0' + compile 'com.android.support:design:24.2.0' + testCompile 'junit:junit:4.12' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c3e02d0..45d9136 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,11 @@ + + + + + @@ -17,7 +22,12 @@ - + + + + \ No newline at end of file diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/Action.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/Action.java new file mode 100644 index 0000000..9324a3f --- /dev/null +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/Action.java @@ -0,0 +1,10 @@ +package com.aspsine.fragmentnavigator.demo; + +/** + * Created by aspsine on 16/9/3. + */ + +public class Action { + public static final String LOGIN = Action.class.getName() + ".LOGIN"; + public static final String LOGOUT = Action.class.getName() + ".LOGOUT"; +} diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/MainActivity.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/MainActivity.java deleted file mode 100644 index 7272098..0000000 --- a/app/src/main/java/com/aspsine/fragmentnavigator/demo/MainActivity.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.aspsine.fragmentnavigator.demo; - -import android.content.Intent; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; - -import com.aspsine.fragmentnavigator.FragmentNavigator; - -public class MainActivity extends AppCompatActivity implements BottomNavigatorView.OnBottomNavigatorViewItemClickListener { - - private static final int DEFAULT_POSITION = 0; - - private FragmentNavigator mNavigator; - - private BottomNavigatorView bottomNavigatorView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - mNavigator = new FragmentNavigator(getSupportFragmentManager(), new FragmentAdapter(), R.id.container); - mNavigator.setDefaultPosition(DEFAULT_POSITION); - mNavigator.onCreate(savedInstanceState); - - bottomNavigatorView = (BottomNavigatorView) findViewById(R.id.bottomNavigatorView); - if (bottomNavigatorView != null) { - bottomNavigatorView.setOnBottomNavigatorViewItemClickListener(this); - } - - setCurrentTab(mNavigator.getCurrentPosition()); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_exception, menu); - return true; - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - mNavigator.onSaveInstanceState(outState); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.action_exception) { - startActivity(new Intent(this, ExceptionActivity.class)); - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onBottomNavigatorViewItemClick(int position, View view) { - setCurrentTab(position); - } - - private void setCurrentTab(int position) { - mNavigator.showFragment(position); - bottomNavigatorView.select(position); - } -} diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/broadcast/BroadcastManager.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/broadcast/BroadcastManager.java new file mode 100644 index 0000000..66e5583 --- /dev/null +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/broadcast/BroadcastManager.java @@ -0,0 +1,40 @@ +package com.aspsine.fragmentnavigator.demo.broadcast; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.support.v4.content.LocalBroadcastManager; + +import com.aspsine.fragmentnavigator.demo.Action; + +/** + * Created by aspsine on 16/9/3. + */ + +public class BroadcastManager { + + public static void register(Context context, BroadcastReceiver receiver, String... actions){ + IntentFilter filter = new IntentFilter(); + for (String action: actions){ + filter.addAction(action); + } + LocalBroadcastManager.getInstance(context).registerReceiver(receiver, filter); + } + + public static void unregister(Context context, BroadcastReceiver receiver){ + LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver); + } + + public static void sendLoginBroadcast(Context context, int position){ + Intent intent = new Intent(Action.LOGIN); + intent.putExtra("EXTRA_POSITION", position); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); + } + + public static void sendLogoutBroadcast(Context context, int position){ + Intent intent = new Intent(Action.LOGOUT); + intent.putExtra("EXTRA_POSITION", position); + LocalBroadcastManager.getInstance(context).sendBroadcast(intent); + } +} diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/ExceptionActivity.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/activity/ExceptionActivity.java similarity index 87% rename from app/src/main/java/com/aspsine/fragmentnavigator/demo/ExceptionActivity.java rename to app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/activity/ExceptionActivity.java index 559eaea..3797d64 100644 --- a/app/src/main/java/com/aspsine/fragmentnavigator/demo/ExceptionActivity.java +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/activity/ExceptionActivity.java @@ -1,10 +1,12 @@ -package com.aspsine.fragmentnavigator.demo; +package com.aspsine.fragmentnavigator.demo.ui.activity; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; +import com.aspsine.fragmentnavigator.demo.R; + public class ExceptionActivity extends AppCompatActivity { @Override diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/activity/LoginActivity.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/activity/LoginActivity.java new file mode 100644 index 0000000..977c808 --- /dev/null +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/activity/LoginActivity.java @@ -0,0 +1,67 @@ +package com.aspsine.fragmentnavigator.demo.ui.activity; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; + +import com.aspsine.fragmentnavigator.demo.R; +import com.aspsine.fragmentnavigator.demo.broadcast.BroadcastManager; +import com.aspsine.fragmentnavigator.demo.utils.SharedPrefUtils; + +public class LoginActivity extends AppCompatActivity implements View.OnClickListener{ + + private EditText etEmail; + private EditText etPassword; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + etEmail = (EditText) findViewById(R.id.et_email); + etPassword = (EditText)findViewById(R.id.et_password); + Button button = (Button) findViewById(R.id.login_in_button); + button.setOnClickListener(this); + } + + @Override + public void onClick(View v) { + if (v.getId() == R.id.login_in_button){ + tryLogin(); + } + } + + void tryLogin(){ + String email = String.valueOf(etEmail.getText()).trim(); + String password = String.valueOf(etPassword.getText()).trim(); + + if(check(email, password)){ + markUserLogin(); + notifyUserLogin(); + finish(); + } + } + + boolean check(String email, String password){ + if (TextUtils.isEmpty(email)){ + etEmail.setError(getString(R.string.error_invalid_email)); + return false; + } + if (TextUtils.isEmpty(password)){ + etPassword.setError(getString(R.string.error_invalid_password)); + return false; + } + return true; + } + + private void markUserLogin(){ + SharedPrefUtils.login(this); + } + + private void notifyUserLogin(){ + BroadcastManager.sendLoginBroadcast(this, 1); + } +} + diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/activity/MainActivity.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/activity/MainActivity.java new file mode 100644 index 0000000..3240a2f --- /dev/null +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/activity/MainActivity.java @@ -0,0 +1,153 @@ +package com.aspsine.fragmentnavigator.demo.ui.activity; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; + +import com.aspsine.fragmentnavigator.FragmentNavigator; +import com.aspsine.fragmentnavigator.demo.Action; +import com.aspsine.fragmentnavigator.demo.R; +import com.aspsine.fragmentnavigator.demo.broadcast.BroadcastManager; +import com.aspsine.fragmentnavigator.demo.ui.adapter.FragmentAdapter; +import com.aspsine.fragmentnavigator.demo.ui.widget.BottomNavigatorView; +import com.aspsine.fragmentnavigator.demo.utils.SharedPrefUtils; + +public class MainActivity extends AppCompatActivity implements BottomNavigatorView.OnBottomNavigatorViewItemClickListener { + + private static final int DEFAULT_POSITION = 0; + + private FragmentNavigator mNavigator; + + private BottomNavigatorView bottomNavigatorView; + + private MenuItem mLoginMenu; + + private MenuItem mLogoutMenu; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + mNavigator = new FragmentNavigator(getSupportFragmentManager(), new FragmentAdapter(), R.id.container); + mNavigator.setDefaultPosition(DEFAULT_POSITION); + mNavigator.onCreate(savedInstanceState); + + bottomNavigatorView = (BottomNavigatorView) findViewById(R.id.bottomNavigatorView); + if (bottomNavigatorView != null) { + bottomNavigatorView.setOnBottomNavigatorViewItemClickListener(this); + } + + setCurrentTab(mNavigator.getCurrentPosition()); + + BroadcastManager.register(this, mLoginStatusChangeReceiver, Action.LOGIN, Action.LOGOUT); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_main, menu); + mLoginMenu = menu.findItem(R.id.action_login); + mLogoutMenu = menu.findItem(R.id.action_logout); + toggleMenu(SharedPrefUtils.isLogin(this)); + return true; + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mNavigator.onSaveInstanceState(outState); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + switch (id) { + case R.id.action_exception: + startActivity(new Intent(this, ExceptionActivity.class)); + return true; + case R.id.action_login: + startActivity(new Intent(this, LoginActivity.class)); + return true; + case R.id.action_logout: + logout(); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void onDestroy() { + BroadcastManager.unregister(this, mLoginStatusChangeReceiver); + super.onDestroy(); + } + + @Override + public void onBottomNavigatorViewItemClick(int position, View view) { + setCurrentTab(position); + } + + private void logout(){ + SharedPrefUtils.logout(this); + BroadcastManager.sendLogoutBroadcast(this, 1); + } + + private void onUserLogin(int position) { + if (position == -1) { + resetAllTabsAndShow(mNavigator.getCurrentPosition()); + } else { + resetAllTabsAndShow(position); + } + toggleMenu(true); + } + + private void onUserLogout(int position) { + if (position == -1) { + resetAllTabsAndShow(mNavigator.getCurrentPosition()); + } else { + resetAllTabsAndShow(position); + } + toggleMenu(false); + } + + private void setCurrentTab(int position) { + mNavigator.showFragment(position); + bottomNavigatorView.select(position); + } + + private void resetAllTabsAndShow(int position){ + mNavigator.resetFragments(position, true); + bottomNavigatorView.select(position); + } + + private void toggleMenu(boolean login) { + if (login) { + mLoginMenu.setVisible(false); + mLogoutMenu.setVisible(true); + } else { + mLoginMenu.setVisible(true); + mLogoutMenu.setVisible(false); + } + } + + private BroadcastReceiver mLoginStatusChangeReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (!TextUtils.isEmpty(action)) { + int position = intent.getIntExtra("EXTRA_POSITION", -1); + if (action.equals(Action.LOGIN)) { + onUserLogin(position); + } else if (action.equals(Action.LOGOUT)) { + onUserLogout(position); + } + } + } + }; +} diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/ChildFragmentAdapter.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/adapter/ChildFragmentAdapter.java similarity index 83% rename from app/src/main/java/com/aspsine/fragmentnavigator/demo/ChildFragmentAdapter.java rename to app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/adapter/ChildFragmentAdapter.java index b1b5933..8cd0a0c 100644 --- a/app/src/main/java/com/aspsine/fragmentnavigator/demo/ChildFragmentAdapter.java +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/adapter/ChildFragmentAdapter.java @@ -1,8 +1,9 @@ -package com.aspsine.fragmentnavigator.demo; +package com.aspsine.fragmentnavigator.demo.ui.adapter; import android.support.v4.app.Fragment; import com.aspsine.fragmentnavigator.FragmentNavigatorAdapter; +import com.aspsine.fragmentnavigator.demo.ui.fragment.MainFragment; /** * Created by aspsine on 16/4/3. diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/FragmentAdapter.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/adapter/FragmentAdapter.java similarity index 80% rename from app/src/main/java/com/aspsine/fragmentnavigator/demo/FragmentAdapter.java rename to app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/adapter/FragmentAdapter.java index e1ff4f4..0bb3635 100644 --- a/app/src/main/java/com/aspsine/fragmentnavigator/demo/FragmentAdapter.java +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/adapter/FragmentAdapter.java @@ -1,8 +1,10 @@ -package com.aspsine.fragmentnavigator.demo; +package com.aspsine.fragmentnavigator.demo.ui.adapter; import android.support.v4.app.Fragment; import com.aspsine.fragmentnavigator.FragmentNavigatorAdapter; +import com.aspsine.fragmentnavigator.demo.ui.fragment.ContactsFragment; +import com.aspsine.fragmentnavigator.demo.ui.fragment.MainFragment; /** * Created by aspsine on 16/3/31. diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/ContactsFragment.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/fragment/ContactsFragment.java similarity index 90% rename from app/src/main/java/com/aspsine/fragmentnavigator/demo/ContactsFragment.java rename to app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/fragment/ContactsFragment.java index 57bcd17..47a49ed 100644 --- a/app/src/main/java/com/aspsine/fragmentnavigator/demo/ContactsFragment.java +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/fragment/ContactsFragment.java @@ -1,4 +1,4 @@ -package com.aspsine.fragmentnavigator.demo; +package com.aspsine.fragmentnavigator.demo.ui.fragment; import android.os.Bundle; @@ -10,6 +10,9 @@ import android.view.ViewGroup; import com.aspsine.fragmentnavigator.FragmentNavigator; +import com.aspsine.fragmentnavigator.demo.R; +import com.aspsine.fragmentnavigator.demo.ui.widget.TabLayout; +import com.aspsine.fragmentnavigator.demo.ui.adapter.ChildFragmentAdapter; /** @@ -57,7 +60,6 @@ public void onTabItemClick(int position, View view) { public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setCurrentTab(mNavigator.getCurrentPosition()); - Log.i(TAG, "onActivityCreated"); } @Override diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/MainFragment.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/fragment/MainFragment.java similarity index 83% rename from app/src/main/java/com/aspsine/fragmentnavigator/demo/MainFragment.java rename to app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/fragment/MainFragment.java index 4c8db6b..58c780b 100644 --- a/app/src/main/java/com/aspsine/fragmentnavigator/demo/MainFragment.java +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/fragment/MainFragment.java @@ -1,4 +1,4 @@ -package com.aspsine.fragmentnavigator.demo; +package com.aspsine.fragmentnavigator.demo.ui.fragment; import android.os.Bundle; @@ -12,6 +12,9 @@ import android.widget.ProgressBar; import android.widget.TextView; +import com.aspsine.fragmentnavigator.demo.R; +import com.aspsine.fragmentnavigator.demo.utils.SharedPrefUtils; + import java.lang.ref.WeakReference; /** @@ -70,7 +73,18 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - loadData(); + if (savedInstanceState == null) { + loadData(); + } else { + mText = savedInstanceState.getString(EXTRA_TEXT); + bindData(); + } + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(EXTRA_TEXT, mText); } @Override @@ -86,7 +100,8 @@ private void showProgressBar(boolean show) { } private void bindData() { - tvText.setText(mText); + boolean isLogin = SharedPrefUtils.isLogin(getActivity()); + tvText.setText(mText + "\n" + "Login:" + isLogin); } /** diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/BottomNavigatorView.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/widget/BottomNavigatorView.java similarity index 96% rename from app/src/main/java/com/aspsine/fragmentnavigator/demo/BottomNavigatorView.java rename to app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/widget/BottomNavigatorView.java index 35220ba..3189e23 100644 --- a/app/src/main/java/com/aspsine/fragmentnavigator/demo/BottomNavigatorView.java +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/widget/BottomNavigatorView.java @@ -1,4 +1,4 @@ -package com.aspsine.fragmentnavigator.demo; +package com.aspsine.fragmentnavigator.demo.ui.widget; import android.content.Context; import android.graphics.PorterDuff; @@ -9,6 +9,8 @@ import android.view.ViewGroup; import android.widget.ImageView; +import com.aspsine.fragmentnavigator.demo.R; + /** * Created by aspsine on 16/3/31. */ diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/TabLayout.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/widget/TabLayout.java similarity index 95% rename from app/src/main/java/com/aspsine/fragmentnavigator/demo/TabLayout.java rename to app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/widget/TabLayout.java index e6488e4..aea266a 100644 --- a/app/src/main/java/com/aspsine/fragmentnavigator/demo/TabLayout.java +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/ui/widget/TabLayout.java @@ -1,4 +1,4 @@ -package com.aspsine.fragmentnavigator.demo; +package com.aspsine.fragmentnavigator.demo.ui.widget; import android.content.Context; import android.util.AttributeSet; @@ -6,6 +6,8 @@ import android.view.ViewGroup; import android.widget.LinearLayout; +import com.aspsine.fragmentnavigator.demo.R; + /** * Created by aspsine on 16/4/1. */ diff --git a/app/src/main/java/com/aspsine/fragmentnavigator/demo/utils/SharedPrefUtils.java b/app/src/main/java/com/aspsine/fragmentnavigator/demo/utils/SharedPrefUtils.java new file mode 100644 index 0000000..0b1ff69 --- /dev/null +++ b/app/src/main/java/com/aspsine/fragmentnavigator/demo/utils/SharedPrefUtils.java @@ -0,0 +1,32 @@ +package com.aspsine.fragmentnavigator.demo.utils; + +import android.content.Context; +import android.content.SharedPreferences; + +/** + * Created by aspsine on 16/9/2. + */ + +public class SharedPrefUtils { + + private static final String SHARED_PREF_LOGIN = "login"; + + public static void login(Context context){ + SharedPreferences sharedPreferences = context.getSharedPreferences(SHARED_PREF_LOGIN, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putBoolean("login", true); + editor.commit(); + } + + public static void logout(Context context){ + SharedPreferences sharedPreferences = context.getSharedPreferences(SHARED_PREF_LOGIN, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putBoolean("login", false); + editor.commit(); + } + + public static boolean isLogin(Context context){ + SharedPreferences sharedPreferences = context.getSharedPreferences(SHARED_PREF_LOGIN, Context.MODE_PRIVATE); + return sharedPreferences.getBoolean("login", false); + } +} diff --git a/app/src/main/res/layout/activity_exception.xml b/app/src/main/res/layout/activity_exception.xml index 8356df9..1f2a152 100644 --- a/app/src/main/res/layout/activity_exception.xml +++ b/app/src/main/res/layout/activity_exception.xml @@ -8,7 +8,7 @@ android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" - tools:context="com.aspsine.fragmentnavigator.demo.ExceptionActivity"> + tools:context="com.aspsine.fragmentnavigator.demo.ui.activity.ExceptionActivity"> + + + + + + + + + +