/* * 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. */ package my.home.lehome.mvp.presenters; import android.app.Activity; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.nfc.NdefMessage; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.Ndef; import android.util.Log; import java.lang.ref.WeakReference; import my.home.common.State; import my.home.common.StateMachine; import my.home.lehome.asynctask.NfcWriteNdefAsyncTask; import my.home.lehome.helper.NFCHelper; import my.home.lehome.mvp.views.NFCDetectView; /** * Created by legendmohe on 15/12/28. */ public class NFCDetectPresenter extends MVPActivityPresenter implements NfcWriteNdefAsyncTask.WriteNdefListener { public static final String TAG = "NFCDetectPresenter"; private WeakReference<NFCDetectView> mNFCDetectView; private PendingIntent mPendingIntent; private IntentFilter[] mNfcIntentFiltersArray; private String[][] mTechListsArray; private StateMachine mStateMachine; enum EVENT { FOUND, CANCEL, FINISH } public NFCDetectPresenter(NFCDetectView view) { this.mNFCDetectView = new WeakReference<>(view); mStateMachine = new StateMachine(); DetectingState detectingState = new DetectingState(); WritingState writingState = new WritingState(); FinishedState finishedState = new FinishedState(); detectingState.linkTo(writingState, EVENT.FOUND); detectingState.linkTo(finishedState, EVENT.CANCEL); writingState.linkTo(finishedState, EVENT.FINISH); mStateMachine.addState(writingState); mStateMachine.addState(finishedState); mStateMachine.addState(detectingState); mStateMachine.setInitState(detectingState); } @Override public void start() { mStateMachine.start(); } @Override public void stop() { } @Override public void onActivityCreate(Activity activity) { if (NFCHelper.isNfcSupported(activity)) this.setupNFCForegroundDispatch(activity); } @Override public void onActivityDestory(Activity activity) { cancelDetecting(); } @Override public void onActivityResume(Activity activity) { if (NFCHelper.isNfcSupported(activity)) this.enableNFCForegroundDispatch(activity); } @Override public void onActivityPause(Activity activity) { if (NFCHelper.isNfcSupported(activity)) this.disableNFCForegroundDispatch(activity); } private void setupNFCForegroundDispatch(Activity activity) { Context context = mNFCDetectView.get().getContext(); mPendingIntent = PendingIntent.getActivity( context, 0, new Intent(context, activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter techTag = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); mNfcIntentFiltersArray = new IntentFilter[]{techTag,}; mTechListsArray = new String[][]{new String[]{Ndef.class.getName()}}; } private void enableNFCForegroundDispatch(Activity activity) { NfcAdapter adapter = NfcAdapter.getDefaultAdapter(activity); adapter.enableForegroundDispatch(activity, mPendingIntent, mNfcIntentFiltersArray, mTechListsArray); } private void disableNFCForegroundDispatch(Activity activity) { NfcAdapter adapter = NfcAdapter.getDefaultAdapter(activity); adapter.disableForegroundDispatch(activity); } public void cancelDetecting() { mStateMachine.postEvent(EVENT.CANCEL); } public void startDetecting() { if (mNFCDetectView.get() != null) { mNFCDetectView.get().onViewStateChange(NFCDetectView.State.DETECTING); } } public void onNewTagDetected(Tag detectedTag) { Log.d(TAG, "found new tag:" + detectedTag); mStateMachine.postEvent(EVENT.FOUND, detectedTag); } @Override public void onWriteFinished(NfcWriteNdefAsyncTask.Result result) { mStateMachine.postEvent(EVENT.FINISH, result); } class DetectingState extends State { public DetectingState() { super("DetectingState"); } @Override public void onStart() { mNFCDetectView.get().onViewStateChange(NFCDetectView.State.DETECTING); } } class WritingState extends State { public WritingState() { super("WritingState"); } @Override public void onEnter(State fromState, Enum<?> event, Object data) { if (fromState.getClass().equals(DetectingState.class)) { mNFCDetectView.get().onViewStateChange(NFCDetectView.State.WRITING); Tag detectedTag = (Tag) data; Context context = mNFCDetectView.get().getContext(); if (NFCHelper.supportedTechs(detectedTag.getTechList())) { if (NFCHelper.writableTag(detectedTag)) { //writeTag here NdefMessage message = NFCHelper.createNdefTextAppMessage(context, mNFCDetectView.get().getTargetContent()); new NfcWriteNdefAsyncTask(NFCDetectPresenter.this, detectedTag).execute(message); } else { mStateMachine.postEvent(EVENT.FINISH, NfcWriteNdefAsyncTask.Result.READONLY); } } else { mStateMachine.postEvent(EVENT.FINISH, NfcWriteNdefAsyncTask.Result.UNSUPPORTED); } } } } class FinishedState extends State { public FinishedState() { super("FinishedState"); } @Override public void onEnter(State fromState, Enum<?> event, Object data) { if (event == EVENT.CANCEL) { mNFCDetectView.get().onViewStateChange(NFCDetectView.State.CANCEL); } else if (event == EVENT.FINISH) { NfcWriteNdefAsyncTask.Result result = (NfcWriteNdefAsyncTask.Result) data; switch (result) { case SUCCESS: mNFCDetectView.get().onViewStateChange(NFCDetectView.State.SUCCESS); break; case UNWRITABLE: case UNSUPPORTED: case READONLY: case OVERSIZE: case EXCEPTION: Log.d(TAG, "tag write fail:" + result); mNFCDetectView.get().showStateToast(result.toString()); mNFCDetectView.get().onViewStateChange(NFCDetectView.State.FAIL); break; default: break; } } } } }