【问题标题】:Android: Change activity state when receiving a phone callAndroid:接听电话时更改活动状态
【发布时间】:2011-04-21 14:45:26
【问题描述】:

在我最新的 android 编程项目中出现了一个问题。 问题是我想更改手机接听电话时启动的活动。 是否可以在接听电话时在联系人姓名后添加一些文字。 我已经在网上搜索可以做到这一点的东西,并且在 API 中查找了几个小时,但我找不到任何东西,是否有可能反映类似的东西? 我做了一个类,当phone_state有来电时监听,可以得到来电号码,但是我想改变屏幕上的外观。

//提前致谢

【问题讨论】:

    标签: android phone-call


    【解决方案1】:

    您不能编辑 InCallScreen 界面。但是您可以使用 toast 在其上方显示一些文本或其他内容,

    类MyToast............

    package i4nc4mp.myLock.phone;
    
    
    /*
     * Copyright (C) 2007 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    
    
    import android.app.INotificationManager;
    import android.app.ITransientNotification;
    import android.content.Context;
    import android.content.res.Resources;
    import android.graphics.PixelFormat;
    import android.os.Handler;
    import android.os.RemoteException;
    import android.os.ServiceManager;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.WindowManager;
        import android.view.WindowManagerImpl;
        import android.widget.TextView;
    
    /**
     * A toast is a view containing a quick little message for the user.  The toast class
     * helps you create and show those.
     * {@more}
     *
     * <p>
     * When the view is shown to the user, appears as a floating view over the
     * application.  It will never receive focus.  The user will probably be in the
     * middle of typing something else.  The idea is to be as unobtrusive as
     * possible, while still showing the user the information you want them to see.
     * Two examples are the volume control, and the brief message saying that your
     * settings have been saved.
     * <p>
     * The easiest way to use this class is to call one of the static methods that constructs
     * everything you need and returns a new Toast object.
     */ 
    public class MyToast {
        static final String TAG = "Toast";
        static final boolean localLOGV = false;
    
        /**
         * Show the view or text notification for a short period of time.  This time
         * could be user-definable.  This is the default.
         * @see #setDuration
         */
        public static final int LENGTH_SHORT = 0;
    
        /**
         * Show the view or text notification for a long period of time.  This time
         * could be user-definable.
         * @see #setDuration
         */
        public static final int LENGTH_LONG = 1;
    
        final Handler mHandler = new Handler();    
        final Context mContext;
        final TN mTN;
        int mDuration;
        int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
        int mX, mY;
        float mHorizontalMargin;
        float mVerticalMargin;
        View mView;
        View mNextView;
    
        /**
         * Construct an empty Toast object.  You must call {@link #setView} before you
         * can call {@link #show}.
         *
         * @param context  The context to use.  Usually your {@link android.app.Application}
         *                 or {@link android.app.Activity} object.
         */
        public MyToast(Context context) {
            mContext = context;
            mTN = new TN();
            mY = context.getResources().getDimensionPixelSize(
                    com.android.internal.R.dimen.toast_y_offset);
        }
    
        /**
         * Show the view for the specified duration.
         */
        public void show() {
            if (mNextView == null) {
                throw new RuntimeException("setView must have been called");
            }
    
            INotificationManager service = getService();
    
            String pkg = mContext.getPackageName();
    
            TN tn = mTN;
    
            try {
    
                service.enqueueToast(pkg, tn, mDuration);
            } catch (RemoteException e) {
                // Empty
            }
        }
    
        /**
         * Close the view if it's showing, or don't show it if it isn't showing yet.
         * You do not normally have to call this.  Normally view will disappear on its own
         * after the appropriate duration.
         */
        public void cancel() {
            mTN.myHide();
            // TODO this still needs to cancel the inflight notification if any
        }
    
        /**
         * Set the view to show.
         * @see #getView
         */
        public void setView(View view) {
            mNextView = view;
        }
    
        /**
         * Return the view.
         * @see #setView
         */
        public View getView() {
            return mNextView;
        }
    
        /**
         * Set how long to show the view for.
         * @see #LENGTH_SHORT
         * @see #LENGTH_LONG
         */
        public void setDuration(int duration) {
            mDuration = duration;
        }
    
        /**
         * Return the duration.
         * @see #setDuration
         */
        public int getDuration() {
            return mDuration;
        }
    
        /**
         * Set the margins of the view.
         *
         * @param horizontalMargin The horizontal margin, in percentage of the
         *        container width, between the container's edges and the
         *        notification
         * @param verticalMargin The vertical margin, in percentage of the
         *        container height, between the container's edges and the
         *        notification
         */
        public void setMargin(float horizontalMargin, float verticalMargin) {
            mHorizontalMargin = horizontalMargin;
            mVerticalMargin = verticalMargin;
        }
    
        /**
         * Return the horizontal margin.
         */
        public float getHorizontalMargin() {
            return mHorizontalMargin;
        }
    
        /**
         * Return the vertical margin.
         */
        public float getVerticalMargin() {
            return mVerticalMargin;
        }
    
        /**
         * Set the location at which the notification should appear on the screen.
         * @see android.view.Gravity
         * @see #getGravity
         */
        public void setGravity(int gravity, int xOffset, int yOffset) {
            mGravity = gravity;
            mX = xOffset;
            mY = yOffset;
        }
    
         /**
         * Get the location at which the notification should appear on the screen.
         * @see android.view.Gravity
         * @see #getGravity
         */
        public int getGravity() {
            return mGravity;
        }
    
        /**
         * Return the X offset in pixels to apply to the gravity's location.
         */
        public int getXOffset() {
            return mX;
        }
    
        /**
         * Return the Y offset in pixels to apply to the gravity's location.
         */
        public int getYOffset() {
            return mY;
        }
    
        /**
         * Make a standard toast that just contains a text view.
         *
         * @param context  The context to use.  Usually your {@link android.app.Application}
         *                 or {@link android.app.Activity} object.
         * @param text     The text to show.  Can be formatted text.
         * @param duration How long to display the message.  Either {@link #LENGTH_SHORT} or
         *                 {@link #LENGTH_LONG}
         *
         */
        public static MyToast makeText(Context context, CharSequence text, int duration) {
            MyToast result = new MyToast(context);
    
            LayoutInflater inflate = (LayoutInflater)
                    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
            TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
            tv.setText(text);
    
            result.mNextView = v;
            result.mDuration = duration;
    
            return result;
        }
    
        /**
         * Make a standard toast that just contains a text view with the text from a resource.
         *
         * @param context  The context to use.  Usually your {@link android.app.Application}
         *                 or {@link android.app.Activity} object.
         * @param resId    The resource id of the string resource to use.  Can be formatted text.
         * @param duration How long to display the message.  Either {@link #LENGTH_SHORT} or
         *                 {@link #LENGTH_LONG}
         *
         * @throws Resources.NotFoundException if the resource can't be found.
         */
        public static MyToast makeText(Context context, int resId, int duration)
                                    throws Resources.NotFoundException {
            return makeText(context, context.getResources().getText(resId), duration);
        }
    
        /**
         * Update the text in a Toast that was previously created using one of the makeText() methods.
         * @param resId The new text for the Toast.
         */
        public void setText(int resId) {
            setText(mContext.getText(resId));
        }
    
        /**
         * Update the text in a Toast that was previously created using one of the makeText() methods.
         * @param s The new text for the Toast.
         */
        public void setText(CharSequence s) {
            if (mNextView == null) {
                throw new RuntimeException("This Toast was not created with Toast.makeText()");
            }
            TextView tv = (TextView) mNextView.findViewById(com.android.internal.R.id.message);
            if (tv == null) {
                throw new RuntimeException("This Toast was not created with Toast.makeText()");
            }
            tv.setText(s);
        }
    
        // =======================================================================================
        // All the gunk below is the interaction with the Notification Service, which handles
        // the proper ordering of these system-wide.
        // =======================================================================================
    
        private static INotificationManager sService;
    
        static private INotificationManager getService() {
            if (sService != null) {
                return sService;
            }
            sService = INotificationManager.Stub.asInterface(ServiceManager.getService("notification"));
            return sService;
        }
    
        private class TN extends ITransientNotification.Stub {
            final Runnable mShow = new Runnable() {
                public void run() {
                    handleShow();
                }
            };
    
            final Runnable mHide = new Runnable() {
                public void run() {
                    handleHide();
                }
            };
    
            private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
    
            WindowManagerImpl mWM;
    
            TN() {
                // XXX This should be changed to use a Dialog, with a Theme.Toast
                // defined that sets up the layout params appropriately.
                final WindowManager.LayoutParams params = mParams;
                params.height = WindowManager.LayoutParams.WRAP_CONTENT;
                params.width = WindowManager.LayoutParams.WRAP_CONTENT;
                params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
                params.format = PixelFormat.TRANSLUCENT;
                params.windowAnimations = com.android.internal.R.style.Theme_Dialog_Alert;
                params.type = WindowManager.LayoutParams.TYPE_TOAST;
                params.setTitle("Toast");
            }
    
            /**
             * schedule handleShow into the right thread
             */
            public void show() {
                if (localLOGV) Log.v(TAG, "SHOW: " + this);
                mHandler.post(mShow);
            }
    
            /**
             * schedule handleHide into the right thread
             */
            public void hide() {
                System.out.println("hide called");
                if (localLOGV) Log.v(TAG, "HIDE: " + this);
               // mHandler.post(mHide);
            }
            public void myHide(){
                System.out.println("my hide called");
                if (localLOGV) Log.v(TAG, "HIDE: " + this);
               mHandler.post(mHide);
            }
            public void handleShow() {
                if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
                        + " mNextView=" + mNextView);
                if (mView != mNextView) {
                    // remove the old view if necessary
                    handleHide();
                    mView = mNextView;
                    mWM = WindowManagerImpl.getDefault();
                    final int gravity = mGravity;
                    mParams.gravity = gravity;
                    if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
                        mParams.horizontalWeight = 1.0f;
                    }
                    if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
                        mParams.verticalWeight = 1.0f;
                    }
                    mParams.x = mX;
                    mParams.y = mY;
                    mParams.verticalMargin = mVerticalMargin;
                    mParams.horizontalMargin = mHorizontalMargin;
                    if (mView.getParent() != null) {
                        if (localLOGV) Log.v(
                                TAG, "REMOVE! " + mView + " in " + this);
                        mWM.removeView(mView);
                    }
                    if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
                    mWM.addView(mView, mParams);
                }
            }
    
            public void handleHide() {
                //System.out.println("handle hid ecalles");
                if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView);
                if (mView != null) {
                    // note: checking parent() just to make sure the view has
                    // been added...  i have seen cases where we get here when
                    // the view isn't yet added, so let's try not to crash.
                    if (mView.getParent() != null) {
                        if (localLOGV) Log.v(
                                TAG, "REMOVE! " + mView + " in " + this);
                        mWM.removeView(mView);
                    }
    
                    mView = null;
                }
            }
        }
    }
    

    //在广播接收器中............

     String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
    
    if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
    toast = new MyToast(context);
    toast.setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);
                toast.setDuration(Toast.LENGTH_SHORT);
     toast.setView(view);  
     toast.show();
      }
     else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
     toast.cancel();
      }
    else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
    toast.cancel();
    
    }
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多