FM上层



FMPlay.java
public void onCreate(Bundle savedInstanceState) {
        Log.d(LOGTAG,"onCreate");
        super.onCreate(savedInstanceState);
//设置全屏模式
        setVolumeControlStream(AudioManager.STREAM_FM);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
                , WindowManager.LayoutParams.FLAG_FULLSCREEN);


        setContentView(R.layout.radio);


//得到FM台列表
        mStationList = FMPlaySharedPreferences.getInstance(this);


        if (!getComponents()) {
            return;
        }


        setUiPower(false, true);


//new 一个Service的作用? 普通的类
        mService = new RadioServiceStub(this, this);   --------important4  


//设置FM存储位置,SDcard首先
        m_recorder = new Recorder();
        m_recorder.setOnStateChangedListener(mOnStateChangedListener);
        registerExternalStorageListener();


        /* changed by qiaozw begin*/ //定义一个轻量级存储perfs?
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        mIsSpeaker = prefs.getBoolean("mIsSpeaker", false);
        /* changed by qiaozw end */


        mReady = false;
        mOver = true;
        mOpenResult = true;
        mDialogs = new Dialog[DIALOG_COUNT];
        mCurrentDialog = NO_DIALOG;


        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
        filter.addAction(Intent.ACTION_FM);
        filter.addAction(Intent.ACTION_HEADSET_PLUG);
        filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        filter.addAction("android.intent.action.TIME_SET");
//注册广播
        registerReceiver(mReceiver, filter);


        //mm04 fix bug 2706
        tmgr = (TelephonyManager) getSystemService("phone");
        tmgr.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }




 protected void onStart() {
        Log.d(LOGTAG,"onStart");
        super.onStart();
//onCreate -> onStart
        if (!mService.bindToService()) {                   -----------------important6
            Log.d(LOGTAG, "fail to bindToService");
            mService = null;
            return;
        }
//判断FM是否已经打开
        if(mPowerChecked && !isFmOn()){         
            mHandler.sendMessage(mHandler.obtainMessage(MSG_OPEN));    --------important1
        }


        //mm04 fix bug 3183
        Intent i = new Intent("com.android.fm.stopmusicservice");
        i.putExtra("playingfm", true);
        this.sendBroadcast(i);
    }
    
    
    FMPlay.java
    private boolean isFmOn(){
        boolean value = false;
        try {
            value = mService.isFmOn();
        } catch (NullPointerException e){
            Log.d(LOGTAG,"mService NullPointerException");
            mService = new RadioServiceStub(this, this);
            if (!mService.bindToService()) {
                Log.d(LOGTAG, "resetMService fail to bindToService");
                mService = null;
                return true;
            }
            isFmOn();
            Log.d(LOGTAG,"mService ok");
        }  catch (Exception e) {
            // TODO Auto-generated catch block
            Log.d(LOGTAG,"mService Exception");
            e.printStackTrace();
            return true;
        }


        return value;
    }
    
    
    RadioServiceStub.java
     public boolean isFmOn() {
        boolean value = false;
        if (mService != null) {
            try {
                value = mService.isFmOn();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return value;
    }
    
    
    IRadioService.aidl
    interface IRadioService
{
    -------------------
    boolean isFmOn();             
    -------------------
}




FMplayService.java
static class ServiceStub extends IRadioService.Stub{
        WeakReference<FMplayService> mService;


        public ServiceStub(FMplayService service) {
            mService = new WeakReference<FMplayService>(service);
        }


        public boolean fmOn() throws RemoteException {
            if(mService != null){
                if(mService.get() != null){
                    return mService.get().fmOn();
                }
            }
            return false;
        }


        -------------------------------------


        public boolean isFmOn() throws RemoteException {                 
            if(mService != null){
                if(mService.get() != null){
                    return mService.get().isFmOn();
                }
            }
            return false;
        }


----------------------------------------
    }
    
    
WeakReference<FMplayService> mService;


WeakReference.java
public class WeakReference<T> extends Reference<T> {}


Reference.java
    /**
     * Returns the referent of the reference object.
     *
     * @return the referent to which reference refers, or {@code null} if the
     *         object has been cleared.
     */
    public T get() {
        return referent;
    }


FMplayService.java
public boolean isFmOn() {
        Log.d(LOGTAG, "isFmOn" + mFmOn);
        return (mReceiver != null) && mFmOn;
    }
    


接-----------important1
frameworks\base\core\java\anrdoid\os\Handler.java
/**
     * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message.
     * 
     * @param what Value to assign to the returned Message.what field.
     * @return A Message from the global message pool.
     */
    public final Message obtainMessage(int what)    //what = MSG_OPEN
    {
        return Message.obtain(this, what);
    }


 public final boolean sendMessage(Message msg)
    {
        return sendMessageDelayed(msg, 0);  //msg.what = MSG_OPEN
    }


frameworks\base\core\java\anrdoid\os\Message.java
public static Message obtain(Handler h, int what) {
        Message m = obtain();
        m.target = h;
        m.what = what;


        return m;
    }




FMPlay.java
private Handler mHandler = new Handler(){                   ------------------------important2  mHandler.sendMessage - > handleMessage
        public void handleMessage(Message msg) {
            Log.d(LOGTAG, "msg.what: " +msg.what+" mOver: "+mOver);
            switch(msg.what) {      //msg.what = MSG_OPEN
            case MSG_ROUTE:
                removeMessages(MSG_ROUTE);
                if (mReady) {
                    showAudioDevice();
                    mService.routeAudio(mIsSpeaker ? FMplayService.RADIO_AUDIO_DEVICE_SPEAKER
                            : FMplayService.RADIO_AUDIO_DEVICE_WIRED_HEADSET);
                } else {
                    Message message = mHandler.obtainMessage(MSG_ROUTE);
                    sendMessageDelayed(message, CHECK_DELAY);
                }
                break;
          ...........................................
            case MSG_OPEN:
                removeMessages(MSG_OPEN);
                if (!mReady) {   //mReady  =false                   
                    sendMessageDelayed(obtainMessage(MSG_OPEN), OPEN_DELAY);
                } else {            ----------------important7


                    if (!isFmOn()) {//fix bug 11354,11420
                        if (System.getInt(getContentResolver(), System.AIRPLANE_MODE_ON, 0) != 0) {
                            showAlertDialog(AIRPLANE_DIALOG);
                            return;
                        }


                        TelephonyManager pm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                        if (pm.getCallState() == TelephonyManager.CALL_STATE_RINGING || pm.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK) {
                            showAlertDialog(PHONE_DIALOG);
                            return;
                        }


                        if (!SystemProperties.getBoolean("ro.device.support.antenna", false)) {
                            if (isHeadsetExists()) {
                                if (mCurrentDialog == HEADSET_DIALOG) {
                                    closeAlertDialog(HEADSET_DIALOG);
                                }


                                if (mOver == true) {
                                    Log.d(LOGTAG, "showAlertDialog:STARTUP_DIALOG");
                                    showAlertDialog(STARTUP_DIALOG);
                                    mOpenThread = createOpenThread();
                                    Log.d(LOGTAG, " create thread when use ");
                                    mOpenThread.start();
                                }
                            } else {
                                if (mCurrentDialog != HEADSET_DIALOG) {
                                    if (mCurrentDialog != NO_DIALOG) {
                                        closeAlertDialog(mCurrentDialog);
                                    }
                                    showAlertDialog(HEADSET_DIALOG);
                                }
                                return;
                            }
                        }
                    } else {
                        setUiPower(true, false);
                    }
                }
                break;
           ...................................................
           
            default:
            }
        }
    };




frameworks\base\core\java\anrdoid\os\Handler.java
 public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }




public boolean sendMessageAtTime(Message msg, long uptimeMillis)   -----------------------important3
    {
        boolean sent = false;
        MessageQueue queue = mQueue;     
        if (queue != null) {
            msg.target = this;           ----------------走这边
            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
        else {
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        return sent;
    }




public Handler() {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }


        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = null;
    }




frameworks\base\core\java\anrdoid\os\Looper.java
/**
     * Return the Looper object associated with the current thread.  Returns
     * null if the calling thread is not associated with a Looper.
     */
    public static Looper myLooper() {
        return sThreadLocal.get();
    }
具体看Looper.java,
 public static void prepareMainLooper() {
        prepare();
        setMainLooper(myLooper());
        myLooper().mQueue.mQuitAllowed = false;
    }


 public static void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
    }
.............................
所以important3中queue != null


在onCeate()时important4 
mService = new RadioServiceStub(this, this);            ----------------------5
if (!mService.bindToService()) {                   -----------------6
public boolean bindToService() {
        mContext.startService(new Intent(mContext, FMplayService.class));
        mBinder = new BinderCallback(mCallback);
        return mContext.bindService((new Intent()).setClass(mContext, FMplayService.class), mBinder,
                Context.BIND_AUTO_CREATE);
    }




    private class BinderCallback implements ServiceConnection {
        private ServiceConnection mCallback;


        public void onServiceDisconnected(ComponentName name) {
            if (mCallback != null) {
                mCallback.onServiceDisconnected(name);
            }
            mService = null;
        }
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = IRadioService.Stub.asInterface(service);
            if (mCallback != null) {
                mCallback.onServiceConnected(name, service);             -------------------------????
            }
        }
        public BinderCallback(ServiceConnection callback) {
            mCallback = callback;
        }
    }


public RadioServiceStub(Context context, ServiceConnection callback) {
        mContext = context;
        mCallback = callback;           ---------------------important5回归 -> 5
        mService = null;
        mBinder = null;
    }


public void onServiceConnected(ComponentName name, IBinder service) {
        mReady = true;
        Log.d(LOGTAG, "mReady = true");
    }


所以此时mReady = true;


case MSG_OPEN:
    走 -> ----------------important7
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值