15

嗨,我在这里和谷歌上到处搜索,没有得到正确的答案。所以我发布了一个新问题:

我有几个与 1.6 到 2.3 完美配合的 Android 应用程序......

但是现在,使用 Android 4.0 (ICS),我有用户报告说,当应用程序启动时,主页上的屏幕正在闪烁,除了“主页”和强制停止应用程序之外什么都做不了......(然后。你可以开始再次应用该应用程序,它最终可以工作...:O)

我已经在模拟器和包括带有 Android 4.0.4 的 Galaxy S 3 在内的多个设备上测试了该应用程序,但我永远无法重现该问题!:(( 看来问题主要出在 HTC One 上...

这是活动的简单代码

public class WelcomePage extends Activity {


/** Called when the activity is first created. */
@Override

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Eula.show(this);
    //on lui associe le layout 
    setContentView(R.layout.main);

    //on récupère tous les éléments
    Button buttonGuide = (Button)findViewById(R.id.buttonOui);
    Button buttonHotel = (Button)findViewById(R.id.buttonNon);
    Button buttonMap = (Button)findViewById(R.id.buttonMapg);
    Button buttonMaps = (Button)findViewById(R.id.buttonMaps);
    Button buttonMapb = (Button)findViewById(R.id.buttonMapb);
    Button buttonTwitt = (Button)findViewById(R.id.buttonTwitt);
    Button buttonFaceb = (Button)findViewById(R.id.buttonFaceb);
    Button buttonGoogle = (Button)findViewById(R.id.buttonGoogle);
    Button buttonGeoloc = (Button)findViewById(R.id.buttonGeoloc);

    OnClickListener onClickLister = new OnClickListener() {

        public void onClick(View v){
            Intent intent;
            switch(v.getId()){
            //si on a cliqué sur le button Oui
            case R.id.buttonOui:
                Bundle objetbunble = new Bundle();
                objetbunble.putString("titre", "Phuket");
                String lurl;
                if (getString(R.string.lnguserlook).equals("en")) { lurl = "phuketen"; } else { lurl = "phuket"; }
                objetbunble.putString("url", lurl);
                intent = new Intent(WelcomePage.this, AfficheGuide.class);
                Toast.makeText(WelcomePage.this, getString(R.string.titguid)+" Phuket "+getString(R.string.titguid2), Toast.LENGTH_SHORT).show();
                ((MyApplication)getApplicationContext()).setIsPagehelp(false);  // pas Help en globale
                //On affecte à l'Intent le Bundle que l'on a créé
                intent.putExtras(objetbunble);
                startActivity(intent);
                break;
            case R.id.buttonNon:
              Toast.makeText(WelcomePage.this, getString(R.string.hotellist), Toast.LENGTH_SHORT).show();
                //On créé l'Intent qui va nous permettre d'afficher l'autre Activity
                intent = new Intent(WelcomePage.this, ListeDestinationAll.class);
                startActivity(intent);
                break;
            case R.id.buttonGeoloc:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else {  Toast.makeText(WelcomePage.this, "Geolocalisation", Toast.LENGTH_SHORT).show();
                        intent = new Intent(WelcomePage.this, AfficheGeoloc.class);
                        startActivity(intent); 
                }
                break;
            case R.id.buttonMapg:
                Toast.makeText(getApplicationContext(), getString(R.string.map1), Toast.LENGTH_SHORT).show();
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else { 
                        Toast.makeText(WelcomePage.this, "Phuket", Toast.LENGTH_SHORT).show();
                        objetbunble = new Bundle();
                        //Cela fonctionne plus ou moins comme une HashMap, on entre une clef et sa valeur en face
                        objetbunble.putString("titre", "Phuket");
                        objetbunble.putString("url", "phuket&titre=Phuket");
                        intent = new Intent(WelcomePage.this, AfficheMaps.class);
                        //On affecte à l'Intent le Bundle que l'on a créé
                        intent.putExtras(objetbunble);
                        startActivity(intent); 
                }
                break;
            case R.id.buttonMaps:
                Toast.makeText(getApplicationContext(), getString(R.string.map2), Toast.LENGTH_SHORT).show();
                Bundle objetbunblemap = new Bundle();
                objetbunblemap.putString("titre", getString(R.string.map2));
                objetbunblemap.putString("url", "pic");
                final Intent intentm;
                intentm = new Intent(WelcomePage.this, ImageViewerJP.class); 
                intentm.putExtras(objetbunblemap);
                startActivity(intentm);
                break;
            case R.id.buttonMapb:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else {  //On créé un objet Bundle, c'est ce qui va nous permetre d'envoyer des données à l'autre Activity
                    objetbunble = new Bundle();
                    objetbunble.putString("titre", getString(R.string.titevent3)+" Phuket");
                    objetbunble.putString("url", getString(R.string.urlevent2)+"phuket");
                    intent = new Intent(WelcomePage.this, AfficheEvents.class);
                    Toast.makeText(WelcomePage.this, getString(R.string.titevent3)+" Phuket", Toast.LENGTH_SHORT).show();
                    //On affecte à l'Intent le Bundle que l'on a créé
                    intent.putExtras(objetbunble);
                    startActivity(intent);
                }
                break;
            case R.id.buttonTwitt:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else { Toast.makeText(WelcomePage.this, "Twitter", Toast.LENGTH_SHORT).show();
                    //On créé l'Intent qui va nous permettre d'afficher l'autre Activity
                    intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("http://mobile.twitter.com/#!/ResaHotelThai"));
                    startActivity(intent);
                }
                break;
            case R.id.buttonGoogle:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else { Toast.makeText(WelcomePage.this, "Google+", Toast.LENGTH_SHORT).show();
                    //On créé l'Intent qui va nous permettre d'afficher l'autre Activity
                    intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("https://plus.google.com/114371498756127408275/posts"));
                    startActivity(intent);
                }
                break;
            case R.id.buttonFaceb:
                if (!(Extras.Internet.isOnline())){ 
                    AlertDialog.Builder builder = new AlertDialog.Builder(WelcomePage.this);
                    builder.setMessage(getString(R.string.txtoffline))
                           .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                    dialog.cancel();
                               }
                           }).create().show(); }        
                else { Toast.makeText(WelcomePage.this, "Facebook", Toast.LENGTH_SHORT).show();
                    //On créé l'Intent qui va nous permettre d'afficher l'autre Activity
                    intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse("http://m.facebook.com/ResaHotelThai"));
                    startActivity(intent);
                }
                break;
            }
        }

    };

    //on affecte aux Button l'écouteur d'évènement
    buttonGuide.setOnClickListener(onClickLister);
    buttonHotel.setOnClickListener(onClickLister); 
    buttonMap.setOnClickListener(onClickLister); 
    buttonMaps.setOnClickListener(onClickLister); 
    buttonMapb.setOnClickListener(onClickLister); 
    buttonTwitt.setOnClickListener(onClickLister); 
    buttonFaceb.setOnClickListener(onClickLister); 
    buttonGoogle.setOnClickListener(onClickLister);
    buttonGeoloc.setOnClickListener(onClickLister);
}

//Méthode qui se déclenchera lorsque vous appuierez sur le bouton menu du téléphone
public boolean onCreateOptionsMenu(Menu menu) {

    //Création d'un MenuInflater qui va permettre d'instancier un Menu XML en un objet Menu
    MenuInflater inflater = getMenuInflater();
    //Instanciation du menu XML spécifier en un objet Menu
    inflater.inflate(R.layout.menu, menu);

    //Il n'est pas possible de modifier l'icône d'entête du sous-menu via le fichier XML on le fait donc en JAVA
    menu.getItem(0).getSubMenu().setHeaderIcon(R.drawable.language);

    return true;
 }

//Méthode qui se déclenchera au clic sur un item
public boolean onOptionsItemSelected(MenuItem item) {
      Intent intent;
     //On regarde quel item a été cliqué grâce à son id et on déclenche une action
     switch (item.getItemId()) {
        case R.id.option:
           Toast.makeText(WelcomePage.this, getString(R.string.language), Toast.LENGTH_SHORT).show();
           return true;
        case R.id.french:
            Locale locale = new Locale("fr"); 
            Locale.setDefault(locale);
            Configuration config = new Configuration();
            config.locale = locale;
            getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
            ((MyApplication)getApplicationContext()).setState("fr");    // passe langue en globale
            Toast.makeText(WelcomePage.this, "Français", Toast.LENGTH_SHORT).show();
            intent = new Intent(WelcomePage.this, WelcomePage.class);
            //On redémarre l'Activity
            startActivity(intent);
            finish();
            return true;
        case R.id.english:
            Locale locale2 = new Locale("en"); 
            Locale.setDefault(locale2);
            Configuration config2 = new Configuration();
            config2.locale = locale2;
            getBaseContext().getResources().updateConfiguration(config2, getBaseContext().getResources().getDisplayMetrics());
            ((MyApplication)getApplicationContext()).setState("en");    // passe langue en globale
            Toast.makeText(WelcomePage.this, "English", Toast.LENGTH_SHORT).show();
            intent = new Intent(WelcomePage.this, WelcomePage.class);
            //On redémarre l'Activity
            startActivity(intent);
            finish();
            return true;
       case R.id.about:
            // Assigne un Layout particulier a la dialogue Box
            LayoutInflater inflater = (LayoutInflater) WelcomePage.this.getSystemService(LAYOUT_INFLATER_SERVICE);
            View layout = inflater.inflate(R.layout.afficheabout,
                                           (ViewGroup) findViewById(R.id.layout_root));
            // Traitement du texte a afficher + linkify pour que le lien soit cliquable
            TextView text = (TextView) layout.findViewById(R.id.text);
            final SpannableString s = new SpannableString("Version 1.1.0\n\n\nwww.bloodico.com\n\nCopyright ©2011/2012\nBloodico Co Ltd");
            text.setText(s);
            Linkify.addLinks(text, Linkify.ALL);
            // Traitement de l'image a afficher a gauche
            ImageView image = (ImageView) layout.findViewById(R.id.image);
            image.setImageResource(R.drawable.sawadi);
            // Construction de la dialogbox
            AlertDialog.Builder adb = new AlertDialog.Builder(WelcomePage.this);
            adb.setView(layout);
            adb.setTitle("GuidePhuket");
            adb.setIcon(R.drawable.ic_launcher);
            //on indique que l'on veut le bouton ok à notre boite de dialogue
            adb.setPositiveButton("Ok", null);
            adb.show();
           return true;
        case R.id.help:
           Toast.makeText(WelcomePage.this, getString(R.string.helptitle), Toast.LENGTH_SHORT).show();
            //On créé un objet Bundle, c'est ce qui va nous permetre d'envoyer des données à l'autre Activity
            Bundle objetbunble = new Bundle();

            //Cela fonctionne plus ou moins comme une HashMap, on entre une clef et sa valeur en face
            objetbunble.putString("titre", getString(R.string.helptitle));
            objetbunble.putString("url", getString(R.string.helpurl));
            intent = new Intent(WelcomePage.this, AfficheGuide.class);
            //On affecte à l'Intent le Bundle que l'on a créé
            intent.putExtras(objetbunble);
                startActivity(intent);
           return true;
        case R.id.morapp:
            Toast.makeText(WelcomePage.this, getString(R.string.morapp), Toast.LENGTH_SHORT).show();
           Intent marketIntent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse("market://search?q=pub:Bloodico+Co+Ltd"));
           startActivity(marketIntent);
           return true;
      }
      return super.onOptionsItemSelected(item);
  }

}

这是使用的布局

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:background="@drawable/fond"
>
  <ImageView  android:id="@+id/imageintro"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/logocompanyfr"
    android:gravity="center_horizontal"
    android:contentDescription="@string/app_name"
    />

        <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      android:layout_marginTop="20dp"
      >
      <Button android:id="@+id/buttonOui"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titreguidebutton" />

     <Button android:id="@+id/buttonNon"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titrehotelbutton" />

      <Button android:id="@+id/buttonGeoloc"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/titregeolocbutton" />

    </LinearLayout>

    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      android:paddingTop="5dp"
      >
     <Button android:id="@+id/buttonMapg"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titreinfobutton" />

      <Button android:id="@+id/buttonMaps"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titremapsbutton" />

      <Button android:id="@+id/buttonMapb"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/titremapbbutton" />

    </LinearLayout>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:orientation="horizontal" >

      <Button android:id="@+id/buttonFaceb"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titrefacebbutton" />

      <Button android:id="@+id/buttonTwitt"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginRight="20dp"
        android:background="@drawable/titretwittbutton" />

      <Button android:id="@+id/buttonGoogle"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/titregooglebutton" />
    </LinearLayout>

</LinearLayout>

这是清单文件的摘录

<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" />
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:name=".MyApplication" android:allowBackup="true" android:screenOrientation="portrait">
    <activity android:name=".WelcomePage" 
              android:screenOrientation="portrait"                
              android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:theme="@android:style/Theme.NoTitleBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

任何帮助将不胜感激,因为我有越来越多的用户关注并且无法找到搜索的方式。

4

1 回答 1

23

终于找到了错误和正确的解决方案!

实际上,只有当人们第一次从陆地模式的屏幕启动应用程序时才会出现问题......应用程序在清单中被强制为纵向,但是,尽管如此,我意识到Android仍然在启动时执行 onConfigurationChanged (当从土地到肖像,例如)

问题是应用程序有 2 种语言,为了在屏幕方向上保持正确的语言,我增加了我自己的 Myapplication(以扩展应用程序)来管理 onConfigurationChanged 并在整个应用程序中设置正确的区域设置!

即使在强制应用程序在 Manifest 中显示肖像后(由于某些原因,前段时间),来自 MyApplication.java 的 onConfigurationChanged 仍然在某些情况下执行......

问题

MyApplication.java 中的代码是

public void onConfigurationChanged(Configuration newConfig)
  {
      super.onConfigurationChanged(newConfig);
      // Set correct language (default or chosen)
      Locale locale = new Locale(getState()); 
      Locale.setDefault(locale);
      newConfig.locale = locale;
      getBaseContext().getResources().updateConfiguration(newConfig, getBaseContext().getResources().getDisplayMetrics());
  }

解决方案

不要直接使用 newConfig,而是按照 Android Developper 的建议制作一个 Modifiable Configuration 对象,然后使用它

public void onConfigurationChanged(Configuration newConfig)
  {
      super.onConfigurationChanged(newConfig);
      // Set correct language (default or chosen)
      Locale locale = new Locale(getState()); 
      Locale.setDefault(locale);
      Configuration config = new Configuration(newConfig); // get Modifiable Config from actual config changed
      config.locale = locale;
      getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
  }

直接加载 newConfog 对象的前一个解决方案在 Android v2.3 之前一直有效,但在 Android 版本 >= 4.0 中不再被接受

现在一切正常!

(特别感谢 Frédéric Espiau 别名Apollidore,因为解决方案来自阅读他的优秀著作“Créez des applications pour Android”)

于 2012-12-10T05:35:01.303 回答