有Activity1、Activity2、Activity3三个Activity,每个Activity上面有一个按钮分别为B1、B2、B3.在AndroidManifest.xml中设置Activity1的intent-filter为
<intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>现在要在Activity1启动后,点击按钮B1跳转到Activity2,同时Activity1调用finish()结束。此时要按BACK键返回,让程序后台运行,在通知栏显示图标。之后在程序退出前,如何让再次点击应用程序列表中的图标时自动跳到Activity2 (即保存程序状态,第一次运行后点击B1由Activity1跳到Activity2,然后按BACK切换回桌面,之后再点程序图标让程序自动切换回按BACK之前的状态)? 在Activity2显示时切换到桌面,再点通知图标后切换会Activity2,在Activity3显示时切换到桌面,再点通知图标后切换会Activity3。仿android版QQ效果,如何实现?求高手指点??

解决方案 »

  1.   

    屏蔽back鍵,按back鍵做home鍵的動作
      

  2.   

    “现在要在Activity1启动后,点击按钮B1跳转到Activity2,同时Activity1调用finish()结束。此时要按BACK键返回,让程序后台运行,在通知栏显示图标。之后在程序退出前,如何让再次点击应用程序列表中的图标时自动跳到Activity2 (即保存程序状态,第一次运行后点击B1由Activity1跳到Activity2,然后按BACK切换回桌面,之后再点程序图标让程序自动切换回按BACK之前的状态)?”
    重载activity2中的boolean onKeyDown (int keyCode, KeyEvent event)方法。让back键实现home键的操作。
    在“Activity2显示时切换到桌面,再点通知图标后切换会Activity2,在Activity3显示时切换到桌面,再点通知图标后切换会Activity3。仿android版QQ效果,如何实现?求高手指点??”
    在minifest中设置ActivityX的launchMode属性值为singleTask,并在ActivityX(X:1-3)切换到桌面的时候调用PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                    new Intent(this, ActivityX.class), 0);   
    notification.setLatestEventInfo(this, getText(R.string.alarm_service_label),
                           text, contentIntent);
    mNM.notify(R.string.xxx, notification);
      

  3.   

    此法只能使点击通知图标时,让跳回按键前的Activity,但在lanucher的应用程序列表里面点图标,还是会跳到第一个Activity,我是想在程序已经运行的情况下点击lanucher中的图标时让其切换回之前的状态而不是重新从Activity1开始
      

  4.   

    这样做也不太合理,假如在启动Activity1之前的Activity并不是桌面,那么按back时,应该返回到启动程序前的Activity,如果按Home键,不管前面有多少Activity,都会切换到桌面。还有就是长按Home,从那里点图标启动和从应用程序列表中点图标进入,效果好像不一样,长按home切换能切换回Activity2,但从应用程序列表中点图标却又跳到Activity1重新开始了
      

  5.   

    请问你什么时候才算是真正的退出呢? 每个activity都是假退出。那啥时候用户才能真正退出?
      

  6.   

    设有退出菜单,只有点击菜单,才认为程序退出,像QQ那种的,只是不了解QQ如何做到让程序进程退出的,一般情况下程序会被缓存到后台,以便下次快速启动,系统会处理资源的回收
      

  7.   

    第一种方法:跳转到Activity2的时候,不要把Activity1 finish掉。在Activity2中截获back按键,进行退出操作。
    第二种方法:在Activity1中截获back按键消息,然后把程序隐藏,不过这样就到了桌面。
      

  8.   

    如果我的程序在跳到Activity2后,在程序点菜单退出之前,Activity1永远都不会再次被使用,那留着也是隐患。像QQ那样,要是登录成功了,登录Activity的存在就没意义。QQ主界面按了BACK键后不一定会返回到桌面(例如在浏览器界面按了QQ通知图标,此时QQ主界面被调出,再按back会回到刚才的浏览器界面)。
    我是想要实现QQ那种效果,按BACK后程序切换到后台,但点击通知图标或lanucher中的图标都会切换回之前的界面,就好像只允许一个程序的实例运行。
      

  9.   

    通过 service ,application 和 sharepreferences 能到达楼主的要求,我写了一个实现基本功能的project,代码比较乱,还需要重构,但是功能都完成了,希望能对楼主有用。
      

  10.   

    代码上传不上来,只有贴在这了。
    package com.alex.mock.qq;import android.app.Notification;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    import android.widget.Toast;
    public class MockQQService extends Service{
        private NotificationManager mNM;    /**
         * Class for clients to access.  Because we know this service always
         * runs in the same process as its clients, we don't need to deal with
         * IPC.
         */
        public class MockQQBinder extends Binder {
            MockQQService getService() {
                return MockQQService.this;
            }
        }    @Override
        public void onCreate() {
            mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        }    @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i("LocalService", "Received start id " + startId + ": " + intent);
            // We want this service to continue running until it is explicitly
            // stopped, so return sticky.
            return START_STICKY;
        }    @Override
        public void onDestroy() {
            // Cancel the persistent notification.
            mNM.cancel(R.string.hello);        // Tell the user we stopped.
            Toast.makeText(this, "service stopped and notification will be removed.", Toast.LENGTH_SHORT).show();
        }    @Override
        public IBinder onBind(Intent intent) {
            return mBinder;
        }    // This is the object that receives interactions from clients.  See
        // RemoteService for a more complete example.
        private final IBinder mBinder = new MockQQBinder();    public void dismissNotification() {
            mNM.cancel(R.string.hello);
        }
        /**
         * Show a notification while this service is running.
         */
        public void showNotification() {
            // Set the icon, scrolling text and timestamp
            Notification notification = new Notification(android.R.drawable.btn_default, "",
                    System.currentTimeMillis());        // The PendingIntent to launch our activity if the user selects this notification
            Class<?> cls = getStartClassFromPrefences();
            PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                    new Intent(this, cls), 0);        // Set the info for the views that show in the notification panel.
            notification.setLatestEventInfo(this, "mock qq title",
                           "mock qq message", contentIntent);        // Send the notification.
            // We use a layout id because it is a unique number.  We use it later to cancel.
            mNM.notify(R.string.hello, notification);
        }    private Class<?> getStartClassFromPrefences() {
            SharedPreferences preference = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
            String name = preference.getString(MockQQApplication.ACTIVITY_NAME, MockQQActivity.class.getSimpleName());
            Class<?> cls = null;
            if(name.equals(MockQQActivity.class.getSimpleName())) {
                cls = MockQQActivity.class;
            } else if (name.equals(ActivityB.class.getSimpleName())){
                cls = ActivityB.class;
            } else if (name.equals(ActivityC.class.getSimpleName())){
                cls = ActivityC.class;
            }
            return cls;
        }
    }
    package com.alex.mock.qq;import android.app.Application;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;public class MockQQApplication extends Application{    public final static String ACTIVITY_NAME = "activity_name";    private MockQQService mBoundService;    @Override
        public void onCreate() {
            super.onCreate();
            bindService(new Intent(this, 
                            MockQQService.class), mConnection, Context.BIND_AUTO_CREATE);
        }    public MockQQService getMockQQService() {
            return mBoundService;
        }    private ServiceConnection mConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName className, IBinder service) {
                // This is called when the connection with the service has been
                // established, giving us the service object we can use to
                // interact with the service.  Because we have bound to a explicit
                // service that we know is running in our own process, we can
                // cast its IBinder to a concrete class and directly access it.
                mBoundService = ((MockQQService.MockQQBinder)service).getService();        }        @Override
            public void onServiceDisconnected(ComponentName className) {
                // This is called when the connection with the service has been
                // unexpectedly disconnected -- that is, its process crashed.
                // Because it is running in our same process, we should never
                // see this happen.
                mBoundService = null;
            }
        };}
      

  11.   

    BaseActivity  for activityA activityB activityCpackage com.alex.mock.qq;import android.app.Activity;
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.Editor;
    import android.os.Bundle;public abstract class BaseActivity extends Activity{    MockQQApplication mApplication;    @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }    @Override
        protected void onResume() {
            super.onResume();
            mApplication = (MockQQApplication) getApplicationContext();
            MockQQService boundService = mApplication.getMockQQService();
            if(boundService != null) {
                boundService.dismissNotification();
            }
        }    @Override
        public void onBackPressed() {
            SharedPreferences preference = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
            Editor editor = preference.edit();
            editor.putString(MockQQApplication.ACTIVITY_NAME, getActivityName());
            editor.commit();
            mApplication.getMockQQService().showNotification();
            finish();
        }    abstract public String getActivityName();
    }
    Activity Apackage com.alex.mock.qq;import android.content.Context;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.TextView;public class MockQQActivity extends BaseActivity {    @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_layout);
            startActivityFromPreferencesIfNeed();
            TextView activityName = (TextView) findViewById(R.id.activity_name);
            activityName.setText("activity A");
        }    private void startActivityFromPreferencesIfNeed() {
            SharedPreferences preference = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
            String name = preference.getString(MockQQApplication.ACTIVITY_NAME, MockQQActivity.class.getSimpleName());
            Class<?> cls = null;
            if (name.equals(ActivityB.class.getSimpleName())){
                cls = ActivityB.class;
            } else if (name.equals(ActivityC.class.getSimpleName())){
                cls = ActivityC.class;
            }
            if(cls != null) {
                Intent intent = new Intent(this, cls);
                startActivity(intent);
                finish();
            }
        }    public void onButtonClick(View v) {
            Intent intent = new Intent(this, ActivityB.class);
            startActivity(intent);
            finish();
        }    @Override
        public String getActivityName() {
            return getLocalClassName();
        }
    }package com.alex.mock.qq;import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.TextView;public class ActivityB extends BaseActivity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_layout);
            TextView activityName = (TextView) findViewById(R.id.activity_name);
            activityName.setText("activity B");
        }    public void onButtonClick(View v) {
            Intent intent = new Intent(this, ActivityC.class);
            startActivity(intent);
            finish();
        }    @Override
        public String getActivityName() {
            return getLocalClassName();
        }
    }package com.alex.mock.qq;import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.TextView;public class ActivityC extends BaseActivity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_layout);
            TextView activityName = (TextView) findViewById(R.id.activity_name);
            activityName.setText("activity C");
        }    public void onButtonClick(View v) {
            Intent intent = new Intent(this, MockQQActivity.class);
            startActivity(intent);
            finish();
        }    @Override
        public String getActivityName() {
            return getLocalClassName();
        }
    }
    Manifest.xml<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.alex.mock.qq"
          android:versionCode="1"
          android:versionName="1.0">
        <uses-sdk android:minSdkVersion="8" />    <application android:name="MockQQApplication"
            android:icon="@drawable/icon" android:label="@string/app_name">
            <activity android:name=".MockQQActivity"
                      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=".ActivityB"
                      android:label="@string/app_name">
            </activity>        <activity android:name=".ActivityC"
                      android:label="@string/app_name">
            </activity>        <service android:name=".MockQQService" />
        </application>
    </manifest>
      

  12.   

    非常感谢您提供的代码,我试了下可以实现部分功能,有一些地方还需优化,在Manifest中申明Activity时需指定"singleTask"运行模式。在每个继承的子Activity中都有public void onButtonClick(View v)方法,这个是系统回调的吗?什么情况下会被调用?参数View v的值从哪来?能否贴上activity_layout.xml的内容,小弟不胜感激!
    假如程序的进程被其他程序杀死,那么sharedpreferences的值是否会残留?导致下次启动时启动了错误的Activity(我是想要程序真实退出后,再次启动,重新从第一个Activity开始运行)?本来是想加个退出菜单,在点击时清空sharedpreferences的值,以便下次重新从第一个Activity开始,但这样也不能保证在被其他程序杀掉时能清空sharedpreferences
      

  13.   

    你切换到桌面了会调用OnPause()方法,在这里做相应的处理,可以在数据库存个值什么的记录一下,下次再点进来了,检测数据库若有值了,就直接跳到activity2
      

  14.   

    <?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">
        <TextView android:id="@+id/activity_name"
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" />    <Button
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="Start Activity"
            android:onClick="onButtonClick"/>
    </LinearLayout>
      

  15.   

    请问该如何才能够复写back键来实现home的功能?求大侠帮助。