问题
I've seen articles and articles on hiding the navigation bar for android application through java. However, what I would like to know, is how do I remove the navigation bar through a pure android c++ native-activity application for a full-screen application(game)(NO JAVA AT ALL!). Full-screen from the android manifest works at hiding the top bar, but the navigation bar stays visible.
This is the Navigation Bar that I wish to remove.
I've searched through books with no luck, there's is no actual documentation for native-activity and google searches result in nothing. There is only the comments inside some of the header files which are tiny comments that don't even help. It seems the topic regarding pure c++ android applications is a black spot yet a lot of games that are coming out on the market are written in c++.
I've also tried setting:
AConfiguration_setNavHidden(m_app->config, ACONFIGURATION_NAVHIDDEN_YES);
But it seems to do nothing, in fact all the AConfiguratin_setXXX seem to do nothing. Perhaps I'm calling it in the wrong place? I've been calling it during APP_CMD_INIT_WINDOW after creating the window. Where should I be calling this function?
回答1:
So! If anyone is curious, I did come up with an answer from rummaging through one of Microsoft's teapot examples. And this is what I came up with:
public class NameOfActivity extends NativeActivity {
void setImmersiveSticky() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
int SDK_INT = android.os.Build.VERSION.SDK_INT;
if (SDK_INT >= 19) {
setImmersiveSticky();
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
setImmersiveSticky();
}
});
}
super.onCreate(savedInstanceState);
}
@Override
protected void onResume() {
//Hide toolbar
int SDK_INT = android.os.Build.VERSION.SDK_INT;
if (SDK_INT >= 11 && SDK_INT < 14) {
getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
} else if (SDK_INT >= 14 && SDK_INT < 19) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LOW_PROFILE);
} else if (SDK_INT >= 19) {
setImmersiveSticky();
}
super.onResume();
}
}
The pure c++ android development still uses java, it gets it from the source inside the android SDK directory. What you can do is extend the NativeActivity with a few additional tweaks. Inside the manifest all you have to do is:
android:hasCode="true"
and then the most importan part is to change the activity name from
android:name="android.app.NativeActivity"
to
android:name="com.example.package.NameOfActivity"
It will still call the android main and set it up just like a regular native activity, but now it gives you a completely full-screen. I hope this helps someone out there. It took me a days of searching for answers, and this is what I could come up with!
GOOD LUCK!
回答2:
I found this piece of code which works (requiring API level > 19). Just call the function at the beginning of main().
void AutoHideNavBar(struct android_app* state)
{
JNIEnv* env{};
state->activity->vm->AttachCurrentThread(&env, NULL);
jclass activityClass = env->FindClass("android/app/NativeActivity");
jmethodID getWindow = env->GetMethodID(activityClass, "getWindow", "()Landroid/view/Window;");
jclass windowClass = env->FindClass("android/view/Window");
jmethodID getDecorView = env->GetMethodID(windowClass, "getDecorView", "()Landroid/view/View;");
jclass viewClass = env->FindClass("android/view/View");
jmethodID setSystemUiVisibility = env->GetMethodID(viewClass, "setSystemUiVisibility", "(I)V");
jobject window = env->CallObjectMethod(state->activity->clazz, getWindow);
jobject decorView = env->CallObjectMethod(window, getDecorView);
jfieldID flagFullscreenID = env->GetStaticFieldID(viewClass, "SYSTEM_UI_FLAG_FULLSCREEN", "I");
jfieldID flagHideNavigationID = env->GetStaticFieldID(viewClass, "SYSTEM_UI_FLAG_HIDE_NAVIGATION", "I");
jfieldID flagImmersiveStickyID = env->GetStaticFieldID(viewClass, "SYSTEM_UI_FLAG_IMMERSIVE_STICKY", "I");
const int flagFullscreen = env->GetStaticIntField(viewClass, flagFullscreenID);
const int flagHideNavigation = env->GetStaticIntField(viewClass, flagHideNavigationID);
const int flagImmersiveSticky = env->GetStaticIntField(viewClass, flagImmersiveStickyID);
const int flag = flagFullscreen | flagHideNavigation | flagImmersiveSticky;
env->CallVoidMethod(decorView, setSystemUiVisibility, flag);
state->activity->vm->DetachCurrentThread();
}
来源:https://stackoverflow.com/questions/41059909/hiding-the-navigation-bar-in-pure-android-native