始终返回登录屏幕

时间:2012-10-12 23:22:35

标签: java android android-manifest

我的应用程序从Splash activity screen开始持续5秒然后打开Login activity screen然后在您输入正确的用户名和密码后打开Menu activity (listActivity),然后每行点击打开MyCity activity

更新

我想要的是:你在我的应用程序中的任何地方,你出于任何原因离开我的应用程序不仅当你按下主页按钮也是FOR EXAMPLES:

  1. 按主页按钮查看其他应用,然后想要返回我的应用。

  2. 您有关于whatsup或电子邮件的通知显示新消息,您打开您的whatsup或打开电子邮件,然后返回我的应用程序。

  3. 3-您离开手机一段时间后,又想再次查看我的应用程序。

    4-按下电源按钮关闭手机(锁定屏幕),然后打开锁定,想要返回我的应用程序。

    我的意思是你出于任何原因离开我的应用程序,但没有按后退按钮,这将退出整个应用程序 然后想再次返回我的应用程序必须打开  您登录屏幕再次输入您的用户名和密码。

    我为Splash活动和登录活动调用了finish();

    我在清单中的Login活动中尝试了android:clearTaskOnLaunch="true",但它没有。

    任何建议都将受到赞赏,

    请写完整的工作代码。

    登录活动:

     public class Login extends Activity {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
    
        Button b = (Button) findViewById(R.id.loginbutton);
    
      b.setOnClickListener(new OnClickListener() {
    
      public void onClick(View v) {
    
        EditText username = (EditText) findViewById(R.id.login);
        EditText password = (EditText) findViewById(R.id.password);
    
         if(username.getText().toString().length() > 0 && password.getText().
                 toString().length() > 0 ) {
    if(username.getText().toString().equals("test") && password.getText().
                 toString().equals("test")) {
    
    
        Intent intent = new Intent(Login.this, Menu.class);
        startActivity(intent);
           finish(); }
                }   }               
                        });  }  }
    

    菜单活动:

      public class Menu extends ListActivity {
    
          String classes[] = { "City1", "City2", "City3", "City4", "City5"};
    
              @Override
          protected void onCreate(Bundle savedInstanceState) {
             // TODO Auto-generated method stub
             super.onCreate(savedInstanceState);
    
          setListAdapter(new ArrayAdapter<String>(Menu.this,
            android.R.layout.simple_list_item_1, classes));
                                       }
    
         @Override
           protected void onListItemClick(ListView l, View v, int position, long id) {
             // TODO Auto-generated method stub
              super.onListItemClick(l, v, position, id);
             String cheese = classes[position];
       try {
        Class ourClass = Class.forName("com.test.demo.MyCity");
        Intent ourIntent = new Intent(Menu.this, ourClass);
        ourIntent.putExtra("cheese", cheese);
             startActivity(ourIntent);
               } catch (ClassNotFoundException e) {
            e.printStackTrace();
                                }
                        }}
    

    MyCity活动:

       public class MyCity extends Activity {
    TextView tv1;
    String city;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        setContentView(R.layout.city);  
    
        initializeTextViews();}
    
    private void initializeTextViews() {
    
        tv1=(TextView)findViewById(R.id.city_tv);
         city=getIntent().getStringExtra("cheese");
    
    if(city.equalsIgnoreCase("City1")){
    
            tv1.setText(Html.fromHtml(getString(R.string.city1)));}
    
    
        else if(city.equalsIgnoreCase("City2")){
    
            tv1.setText(Html.fromHtml(getString(R.string.city2)));}
    
    
        else if(city.equalsIgnoreCase("City3")){
    
            tv1.setText(Html.fromHtml(getString(R.string.city3)));}
    
    
        else if(city.equalsIgnoreCase("City4")){
    
            tv1.setText(Html.fromHtml(getString(R.string.city4)));}
    
    
        else if(city.equalsIgnoreCase("City5")){
    
            tv1.setText(Html.fromHtml(getString(R.string.city5)));}
    
    
        }}
    

    我的表现:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.test.demo"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="15" />
    
        <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
    
            <activity
                android:name=".Splash"
                android:label="@string/app_name">   
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <activity
                android:name=".Login"
                android:label="@string/app_name" 
                     android:clearTaskOnLaunch="true">
                <intent-filter>
                    <action android:name="com.test.demo.LOGIN" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>
    
            <activity
                android:name=".Menu"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="com.test.demo.MENU" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>
    
                  <activity
                android:name=".MyCity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="com.test.demo.MYCITY" />
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    第二次更新:我达到了我想要的一半,但仍然有一些步骤我无法实现它解释如下:

    android:clearTaskOnLaunch="true"应用于Splash活动,

    并阻止菜单活动上的后退按钮行为:

      @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
           moveTaskToBack(true);
           return true;
                }
        return super.onKeyDown(keyCode, event);
                        } }
    

    现在按下主页按钮离开我的应用程序然后返回我的应用程序:

    直接转到登录活动

    但现在的主要目标是:

    如果:

    当您离开手机时,

    屏幕锁定,或轻按电源按钮以锁定手机。

    来自通知的

    已打开的消息

    来自通知的

    已打开的电子邮件

    你有 CALL 并回答,

    然后返回我的应用它不会进入登录活动,但您将返回到您所在的页面。

    任何建议请,谢谢。

    认真更新:

    我使用了另一个代码来覆盖主页按钮并控制后退按钮而不是将android:clearTaskOnLaunch="true"应用于清单中的Splash活动,只需将下行代码应用于菜单活动:

         @Override
      public boolean onKeyDown(int keyCode, KeyEvent event) {
          if (keyCode == KeyEvent.KEYCODE_BACK) {
           moveTaskToBack(true);
             return true;}
    
        else if (keyCode == KeyEvent.KEYCODE_HOME) { 
         Intent i=new Intent(Menu.this,Login.class);
           startActivity(i);
              finish();
            return true;}
        return super.onKeyDown(keyCode, event);}
    

15 个答案:

答案 0 :(得分:7)

如果我理解正确,那么您的目标是当用户返回您的应用时,必须再次输入用户名和密码。所以我认为实现这一目标最合乎逻辑的方法是在所有活动onResume()方法中添加一个检查,看看你是否有用户名和密码,如果没有,只需转到登录活动即可。最简单的方法是让BaseActivity实现检查,让所有其他活动(spash和login除外)继承该BaseActivity。

在伪java代码中

class BaseActivity extends Activity {

    onResume() {
        super.onResume();
        if (!havingUsernameAndPassword()) {
            startActivity(loginActivity);
            finish();
        }
    }
}

class AnyOfYourActivitiesExceptSpashAndLogin extends BaseActivity {

    onResume() {
        super.onResume();
        // ... further code
    }

    // ... further code
}

havingUsernameAndPassword()的实施当然取决于您在登录活动中存储用户名和密码的方式。一种非常简单的方法是将它们存储在一些静态类成员中,因此只要应用程序运行它们就可以存活。

更新:更具体的例子

我做了一个新的例子,展示了如何在登录时保存登录数据,以便稍后检查。实际上,只有一面旗帜就更有意义了。和一些用户ID,但这取决于你的实现,所以我会在这里坚持用户名/密码。

class SimpleDataHolder {
    public static String username = null;
    public static String password = null;
}

class LoginActivity extends Activity {

    // ...
    // when user has entered valid username/password, store them in SimpleDataHolder:
    SimpleDataHolder.username = username;  // <-- store username entered
    SimpleDataHolder.password = password;  // <-- store password entered
}

class BaseActivity extends Activity {

    onResume() {
        super.onResume();
        if (SimpleDataHolder.username == null || SimpleDataHolder.password == null) {
            startActivity(loginActivity); // <-- go to login
            finish();                     // <-- end current activity
        }
    }
}

class AnyOfYourActivitiesExceptSpashAndLogin extends BaseActivity {

    // ... your existing code (if any)

    onResume() {
        super.onResume();  // <-- this calls BaseActivity.onResume() which checks username/password
        // ... your existing code (if any)
}

答案 1 :(得分:4)

应用程序 CAN NOT 重新路由主页按钮而不修改框架代码。对不起,这是可能......

答案 2 :(得分:4)

对于您的第二个更新问题,我建议覆盖OnResume()方法,但您必须小心处理其中的操作。我还建议你研究android lifecycle的工作原理。

答案 3 :(得分:3)

这是我的建议:

keySharedPreferences名为退出。在onCreate()中将exit的值设置为 false

public void onCreate(Bundle ..)
{
 SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
 SharedPreferences.Editor editor=preferences.edit();
 editor.putString("exit","false");
 editor.commit();
 .....  
}

然后在onResume()中检查退出的值。如果是,请将用户带到登录屏幕,否则不要做任何事情。

public void onResume()
{
 super.onResume();
 SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
 String exit=preferences.getString("exit","");
 if(exit.equals("true"))
 {
   Intent i=new Intent(this_activity.thi,login_activity.class);
   startActivity(i);
  finish()
 }
}

然后在onPause()中将exit的值设置为 true

public void onPause()
{
 super.onPause();
 SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
     SharedPreferences.Editor editor=preferences.edit();
     editor.putString("exit","true");
     editor.commit();
}

你说你照顾过backbutton。那应该这样做。您的应用将始终返回登录屏幕。

答案 4 :(得分:2)

另一种解决方法是创建一个活动(FinisherActivity)并在其onCreate()方法中调用finish()。然后,只要您需要按下主页按钮或后退按钮完成活动并防止其停留在堆栈上,只需使用Intent来调用FinisherActivity。但请记住setFlags意图使用Intent.FLAG_ACTIVITY_CLEAR_TOP ...我知道它不是一种有效的方法,但它应该有效..

答案 5 :(得分:2)

Here is the solution I came up with.

请在博客文章末尾下载该项目并进行测试。

经过测试:

  • 三星S3运行android 4.0.4
  • 运行android 2.3.1的模拟器

基本想法:我们将创建一个RequireLoginActivity,除了LoginActivity之外,我们的所有活动都会扩展它。

调用 onResume 函数时应捕获三种情况:

  1. 使用startActivity的风格从一个RequireLoginActivity跳转到另一个RequireLoginActivity。
  2. 通过完成当前活动,从一个RequireLoginActivity跳回到之前的RequireLoginActivity。
  3. 隐藏后返回RequireLoginActivity(我们应该在此处显示登录信息!)
  4. 我的解决方案的基本思路是拥有2个计数器:已启动活动的数量( startCounter )和已暂停活动的数量( pauseCounter )。每次活动开始时,我们都会增加 startCounter 。同样,当活动暂停时, pauseCounter 应该递增。在我们的 onResume 函数中,我们将通过比较2个计数器来决定是否进入登录。如果2个计数器相等,我们将gotoLogin()!

    让我解释一下: 在任何时候,案例1都可以被捕获,因为在开始新活动时,我们的 startCounter 总是比 pauseCounter 更大。这是真的,因为我们总是会有一个额外的活动开始但没有暂停。

    此外,案例3很容易被捕获,因为一旦你离开我们的应用程序,比如说,使用HOME按钮,我们将增加 pauseCounter ,2个计数器将变得相等。应用程序恢复后, onResume 将决定 gotoLogin ()。

    案例2有点棘手,但也很简单。诀窍是覆盖 finish ()函数并递减 startCounter 一次,并将 pauseCounter 递减两次。请记住,在完成活动时,会调用 onPause 并且我们的计数器是相同的。现在通过减少 startCounter 一次和 pauseCounter 两次,我们最终返回到上一个活动的计数器值,而 startCounter 将保持更大<当前一个活动恢复时,strong> pauseCounter 加1。

答案 6 :(得分:1)

其实我不认为我确定你究竟是什么问题,你想按下Android设备内置的Home Key并开始活动吗?

Homekey listener

试试这个: 如果它工作那么真棒,只是通过在那里调用你的登录活动的意图

@Override
    public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.KEYCODE_HOME) { 
            Toast.makeText(MainActivity.this, "Home Key is pressed
                    Toast.LENGTH_LONG).show();
            return true;
        }
        Toast.makeText(MainActivity.this, "Didnt work", Toast.LENGTH_SHORT)
                .show();
        return super.dispatchKeyEvent(e);
    };

答案 7 :(得分:1)

您无法覆盖主页按钮的默认行为。单击后退按钮可以获得所需的结果,主页按钮的默认行为是转到主屏幕。我的建议覆盖后退按钮。然后正确使用意图和设置标志,您可以转到登录屏幕。

   @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
        super.onKeyDown(keyCode, event);
        switch(keyCode)
        {
        case KeyEvent.KEYCODE_BACK:
        Intent i= new Intent("yourpackage.login"); 
        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_NO_HISTORY); 
        startActivity(i);
        finish();
        break;  
        }
        return super.onKeyDown(keyCode, event);
    }

答案 8 :(得分:1)

你问的是反对android的工作方式。

当用户按下主页按钮时,他希望当他返回应用程序时,一切都将保持原样,除非他不在那里很长时间或者他是否运行了资源消耗应用程序。

就好像在Windows上,当您点击ALT + TAB时,您不会期望在电子邮件客户端(或信使,或您使用的任何应用程序)上看到登录。

在任何情况下,您都可以将onWindowFocusChanged与任何functions of activity(onResume,onStart,onRestart,onPause,onStop,...)一起使用,并且只处理您希望使用的相关案例。

答案 9 :(得分:1)

这是不可能的,因为主页按钮是调用启动器应用程序的专用按钮,但您可以将应用程序作为启动器应用程序,例如在自助服务终端模式下运行,请参阅itit

在启动器活动上启用活动,在manifest.xml

上的itentfilter上添加此项
<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.HOME" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

答案 10 :(得分:1)

您的代码几乎是正确的:要在启动应用程序时清除活动堆栈,您应该将android:clearTaskOnLaunch="true" 添加到根活动,即Splash,而不是{{ 1}}(它将是第一个运行的,请参阅this question确定根活动)!

来自documentation:

  

此属性仅对启动新任务的活动有意义   (根活动); 在所有其他活动中被忽略   任务。

因此,如果您将清单中的属性从Login移动到Login,它应该有效,您的应用程序将始终以启动画面开始。

更新:要在来电,屏幕锁定或通知中重新启动您的应用,您必须将Splash(文档here)添加到您的所有其他活动中,或者在所有android:noHistory="true"方法中调用finish()

值得一提的是,我们的答案是如此不同和复杂,因为你想要实现的是完全违背核心Android概念(例如,here是关于退出应用程序的好文章),所以真的,在私人应用程序之外不要做这样的事情。

答案 11 :(得分:1)

很难确切地说出你在问什么,但我相信这正是你在寻找的:How to make splash screen not to load if app is already in memory。总结一下我的帖子:

这是一个设计问题。您的启动器活动不应该是您的启动画面活动。而是在主活动的onCreate方法中打开您的启动活动。这样,如果它是新打开的,则调用onCreate并显示启动画面。否则,如果仅恢复应用程序,调用onResume,则不会调用打开启动画面活动。

然后你可以将你的清单改为:

<activity
        android:name=".ui.MainActivity"
        android:noHistory="true"
        android:screenOrientation="portrait"
        android:label="@string/app_name">

    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>

<activity android:name=".ui.SplashActivity"/>

答案 12 :(得分:1)

您是否在Android Manifest中尝试过android:noHistory活动属性(针对您的每项活动)?这听起来就像你正在寻找的。

答案 13 :(得分:1)

除了登录活动之外,您应该在所有活动finish()方法中调用onPause()。您可以使用startActivity(new Intent (this, LoginPage.this))方法拨打onResume()。因此,每当活动进入前台时,用户将再次被重定向到“登录”页面。

答案 14 :(得分:0)

我的努力可能对您有所帮助,我已成功覆盖HOME按钮(Android 4.0下方)

您可以根据自己的要求塑造代码。

Answer on SO

Source at GITHUB

您现在可以处理主页按钮,这样您就可以轻松创建自己的逻辑来执行应用程序流程。

这是你的目标事件

@Override
    public boolean dispatchKeyEvent(KeyEvent event) {

        if ( (event.getKeyCode() == KeyEvent.KEYCODE_HOME) && isLock) {
             //Logic when Home button pressed
            return true;
        }
        else
            return super.dispatchKeyEvent(event);
    }

希望这肯定能满足我们的要求。

注意:所有这些都是为了管理您可以管理的其他人的Home按钮