Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)

本文主要对NTAG I2C APP源代码中的一个重要Activity——AuthActivity的代码进行解析

前文已经提到,在showAuthDialogFlag为true且mAuthStatus这个变量不等于Disabled的前提下

跳转到 AuthActivity

(见https://blog.****.net/qq_24118527/article/details/82951201

首先是7种认证状态的定义,使用的是枚举类型

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)

然后密码的定义,同样使用的是枚举类型

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)


OnCreate

下面这个图片里的代码我暂时没看明白

其中putExtra是通过intent传递数据的核心方法,而相对应的,getParcebleExtra是接收传递数据的核心方法

可以传递的内容包括八大基本类型/字符串以及实现了Serializable和Parceble接口的对象

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)

就是这些

		// Capture intent to check whether the operation should be automatically launch or not
		mTag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
		if(mTag != null && Ntag_I2C_Demo.isTagPresent(mTag)) {
			demo = new Ntag_I2C_Demo(mTag, this, MainActivity.getPassword(), MainActivity.getAuthStatus());
		}

		// Get the context reference
		mContext = getApplicationContext();

		// Add Foreground dispatcher
		mAdapter = NfcAdapter.getDefaultAdapter(this);
		pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,	getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

常规操作

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)

在UI上更新一下认证状态

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)


OnPause

OnPause这个方法在系统在准备启动或回复另外一个activity时调用,通常在这个方法中将一些消耗CPU的资源释放掉

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)


OnResume

OnResume方法在Activity准备好和用户进行交互的时候调用

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)

接下来这个常规操作,选择我的密码,更新UI,然后调用startDemo函数

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.authPWD1:
			//passwd1Button.setBackgroundResource(R.drawable.btn_blue);// 不要修改颜色20180405
			passwd2Button.setBackgroundColor(Color.BLACK);
			passwd3Button.setBackgroundColor(Color.BLACK);
			
			// Store the password for the auth
			MainActivity.setPassword(Pwds.PWD1.getValue());

			break;
		case R.id.authPWD2:
			passwd2Button.setBackgroundResource(R.drawable.btn_blue);
			passwd1Button.setBackgroundColor(Color.BLACK);
			passwd3Button.setBackgroundColor(Color.BLACK);
			
			// Store the password for the auth
			MainActivity.setPassword(Pwds.PWD2.getValue());
			
			break;
		case R.id.authPWD3:
			passwd3Button.setBackgroundResource(R.drawable.btn_blue);
			passwd1Button.setBackgroundColor(Color.BLACK);
			passwd2Button.setBackgroundColor(Color.BLACK);
			
			// Store the password for the auth
			MainActivity.setPassword(Pwds.PWD3.getValue());
			break;
		default:
			break;
		}
		startDemo(mTag);
	}

startDemo

如果当前的认证状态是Authenticated,就调用demo.Auth方法

关于demo.Auth方法,已经在这篇文章里面写好了

https://blog.****.net/qq_24118527/article/details/82950545

再判断,若demo不为空且demo.isReady,则new一个authTask ,然后再执行之

isReady的实现在之前的文章中介绍过了,很简单

这个AuthTask是一个私有内部类,下一小节介绍

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)


authTask

这是一个异步任务:

启动任务执行的输入参数:Intent

后台任务执行进度:Integer

后台计算结果:Boolean

OnPostExecute(Result result)在后台操作结束时会被调用,计算结果将作为参数传递到此方法中,直接将计算结果传递给UI组件,这个函数里取消显示dialog(可以先看下面两个函数的描述),然后还调用了这个authCompleted(success);

OnPreExecute()在execute函数被调用后立即执行,一般用来在执行任务之前对UI进行标记,这个方法是在UI线程中调用的

里面搞了一个progressDialog的对象,对象的名字就是dialog,Context当然是当前的AutuAcitivity,标题是Authenticating

显示内容是Authenticating against NTAG I2C Plus ...可以取消

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)

doInBackground就是一个认证的过程了,就是demo.Auth,这个不细说了,之前已经写过了

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)


authCompleted

这个函数的实现如下图所示

	public void authCompleted(boolean success) {
		if (success) {
			// Update the status
			if(MainActivity.getAuthStatus() == AuthStatus.Unprotected.getValue()) {
				MainActivity.setAuthStatus(AuthStatus.Authenticated.getValue());
				
				Toast.makeText(mContext, "Tag Successfully protected", Toast.LENGTH_SHORT)
					.show();
				
				// Authenticate in order to let the user use the demos
				demo.Auth(MainActivity.getPassword(), AuthStatus.Protected_RW.getValue());
			} else if(MainActivity.getAuthStatus() == AuthStatus.Authenticated.getValue()) {
				MainActivity.setAuthStatus(AuthStatus.Unprotected.getValue());
				Toast.makeText(mContext, "Tag Successfully unprotected", Toast.LENGTH_SHORT)
					.show();
			} else if(MainActivity.getAuthStatus() == AuthStatus.Protected_RW.getValue()
					|| MainActivity.getAuthStatus() == AuthStatus.Protected_W.getValue()
					|| MainActivity.getAuthStatus() == AuthStatus.Protected_RW_SRAM.getValue()
					|| MainActivity.getAuthStatus() == AuthStatus.Protected_W_SRAM.getValue()) {
				MainActivity.setAuthStatus(AuthStatus.Authenticated.getValue());
				/*Toast.makeText(mContext, "Successful authentication", Toast.LENGTH_SHORT)
					.show();*/
			}
			updateAuthStatus(MainActivity.getAuthStatus());
			
			// Prepare the result intent for the MainActivity
			Intent resultIntent = new Intent();
			setResult(Activity.RESULT_OK, resultIntent);
			finish();
		} else {
			if(MainActivity.getAuthStatus() == AuthStatus.Unprotected.getValue()) {
				Toast.makeText(mContext, "Error protecting tag",
						Toast.LENGTH_SHORT).show();
			} else if(MainActivity.getAuthStatus() == AuthStatus.Authenticated.getValue()) {
				Toast.makeText(mContext, "Error unprotecting tag",
						Toast.LENGTH_SHORT).show();
			} else if(MainActivity.getAuthStatus() == AuthStatus.Protected_RW.getValue()
					|| MainActivity.getAuthStatus() == AuthStatus.Protected_W.getValue()
					|| MainActivity.getAuthStatus() == AuthStatus.Protected_RW_SRAM.getValue()
					|| MainActivity.getAuthStatus() == AuthStatus.Protected_W_SRAM.getValue()) {
				Toast.makeText(mContext, "Password was not correct, please try again",
						Toast.LENGTH_SHORT).show();
			}
		}
	}

看上去这个函数是很复杂的,但是其实就是一些if条件太多,只要稍微整理一下,逻辑还是很清晰的

若你是success

  • 若为Unprotected

置为Authenticated,并调用demo.auth

  • 若为Authenticated

置为Unprotected

  • 若为其他4种状态

置为Authenticated

若你是非success

  • 若为Unprotected
报错"Error protecting tag"
  • 若为Authenticated
报错"Error unprotecting tag"
  • 若为其他4种状态
报错"Password was not correct, please try again"

updateAuthStatus

这个函数没啥好说的,常规操作

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)


onNewIntent

这个函数看不懂,先挖个坑,以后慢慢看

Android程序运行分析——中等复杂程度的NTAG I2C Demo为例(五)