Android片段无法从其他类继承
我目前正在开发一个Android NFC应用程序。此应用程序包含一个Android片段无法从其他类继承,android,android-fragments,navigation-drawer,Android,Android Fragments,Navigation Drawer,我目前正在开发一个Android NFC应用程序。此应用程序包含一个NavigationDrawer,我可以在其中访问3个不同的片段,每个片段对应3个不同的功能。 另一方面,我有一个管理NFC通信的活动。此NFC活动来自NXP源代码,名为“NTAG5开发工具包Android应用程序源代码(REV 1.1)” 按照编写此应用程序的方式,这些片段应该继承自此NFC类,但这显然是不可能的,因为您只能继承自一个类,而包含片段的3个不同类继承自Fragment类 那么我们怎样才能避开这个问题呢 main活
NavigationDrawer
,我可以在其中访问3个不同的片段,每个片段对应3个不同的功能。
另一方面,我有一个管理NFC通信的活动。此NFC活动来自NXP源代码,名为“NTAG5开发工具包Android应用程序源代码(REV 1.1)”
按照编写此应用程序的方式,这些片段应该继承自此NFC类,但这显然是不可能的,因为您只能继承自一个类,而包含片段的3个不同类继承自Fragment
类
那么我们怎样才能避开这个问题呢
main活动
:
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
configureToolbar()
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_memory, R.id.nav_tag, R.id.nav_product), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
private fun configureToolbar() {
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
}
}
open class NFCActivity : AppCompatActivity() {
private val TAG = NFCActivity::class.java.simpleName
private var mNfcAdapter: NfcAdapter? = null
var tag: Tag? = null
private var mPendingIntent: PendingIntent? = null
private lateinit var writeTagFilters: Array<IntentFilter>
private lateinit var mTechLists: Array<Array<String>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
checkNFC()
mNfcAdapter = NfcAdapter.getDefaultAdapter(this)
setNfcIntent()
}
private fun setNfcIntent() {
// Create a generic PendingIntent that will be delivered to this activity. The NFC stack will fill
// in the intent with the details of the discovered tag before delivering it to this activity.
mPendingIntent = PendingIntent.getActivity(this, 0, Intent(
applicationContext, javaClass)
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0)
val tagDetected = IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
writeTagFilters = arrayOf(tagDetected)
mTechLists = arrayOf(arrayOf(
NfcV::class.java.name
))
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == ENABLE_NFC_REQUEST_CODE) {
mNfcAdapter = NfcAdapter.getDefaultAdapter(this)
if (mNfcAdapter!!.isEnabled) {
Toast.makeText(applicationContext, resources.getString(R.string.nfc_not_enabled), Toast.LENGTH_LONG).show()
finish()
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
/**
* Check the availability of NFC and BLE interfaces and let the user enable them
* if not active during the activity creation
*/
private fun checkNFC() {
if (packageManager.hasSystemFeature(PackageManager.FEATURE_NFC)) {
mNfcAdapter = NfcAdapter.getDefaultAdapter(this)
if (mNfcAdapter != null && !mNfcAdapter!!.isEnabled) {
AlertDialog.Builder(this)
.setTitle(resources.getString(R.string.dialog_nfc_not_enabled_title))
.setMessage(resources.getString(R.string.dialog_nfc_not_enabled_msg))
.setPositiveButton(resources.getString(R.string.dialog_nfc_not_enabled_positive_btn),
DialogInterface.OnClickListener { _, _ -> startActivityForResult(Intent(Settings.ACTION_NFC_SETTINGS), ENABLE_NFC_REQUEST_CODE) })
.setNegativeButton(resources.getString(R.string.dialog_nfc_not_enabled_negative_btn),
DialogInterface.OnClickListener { _, _ ->
Toast.makeText(applicationContext, resources.getString(R.string.nfc_not_enabled), Toast.LENGTH_LONG).show()
finish()
}).show()
}
} else {
Toast.makeText(applicationContext, resources.getString(R.string.nfc_not_enabled), Toast.LENGTH_LONG).show()
finish()
}
}
override fun onResume() {
super.onResume()
if (mNfcAdapter != null) {
mNfcAdapter!!.enableForegroundDispatch(this, mPendingIntent, writeTagFilters, mTechLists)
}
}
override fun onPause() {
super.onPause()
if (mNfcAdapter != null) mNfcAdapter!!.disableForegroundDispatch(this)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Log.d(TAG, "Card ID: " + Tools.byteArrayToHex(tag!!.id))
val techList = tag!!.techList
//Check that the discovered tag is a vicinity tag
if (techList[0] == "android.nfc.tech.NfcV") {
val tagUid = tag!!.id
nfcvTag = NfcV.get(tag)
//ISO/IEC 15693 tags can be operated in two modes:
// Select mode and Addressed mode.
//To work in the select mode it is needed to send a SELECT
// command at the beginning of communic.
//In the address mode, the tag UID is sent within each command.
//This application works in SELECT MODE.
val select_command: ByteArray = RFCommands.cmd_select
System.arraycopy(tagUid, 0, select_command, 2, 8)
if (nfcvTag != null) {
try {
nfcvTag!!.connect()
val select_respo = nfcvTag!!.transceive(select_command)
Log.d(TAG, "Select response: " +
Tools.byteArrayToHex(select_respo))
} catch (e: IOException) {
e.printStackTrace()
}
}
}
}
/**
* This method sends RF commands to the connected NFC-V tag,
* the command is included as parameter
* the operation will be useful in MainActivity to distinguish
* the operations in different fragments
*
* @param command
*/
fun sendCommand(command: ByteArray?): ByteArray? {
var response: ByteArray?
try {
response = nfcvTag!!.transceive(command)
Log.d(TAG, "command response: " + Tools.byteArrayToHex(response))
} catch (e: Exception) {
e.printStackTrace()
response = null
}
return response
}
companion object {
private const val ENABLE_NFC_REQUEST_CODE = 0x11
private var nfcvTag: NfcV? = null
}
}
我的3个片段之一:
class MemoryFragment : Fragment() {
private lateinit var memoryViewModel: MemoryViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
memoryViewModel =
ViewModelProvider(this).get(MemoryViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_memory, container, false)
val textView: TextView = root.findViewById(R.id.text_memory)
memoryViewModel.text.observe(viewLifecycleOwner, Observer {
textView.text = it
})
return root
}
}
nfcacity
:
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
configureToolbar()
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(setOf(
R.id.nav_memory, R.id.nav_tag, R.id.nav_product), drawerLayout)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
private fun configureToolbar() {
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
}
}
open class NFCActivity : AppCompatActivity() {
private val TAG = NFCActivity::class.java.simpleName
private var mNfcAdapter: NfcAdapter? = null
var tag: Tag? = null
private var mPendingIntent: PendingIntent? = null
private lateinit var writeTagFilters: Array<IntentFilter>
private lateinit var mTechLists: Array<Array<String>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
checkNFC()
mNfcAdapter = NfcAdapter.getDefaultAdapter(this)
setNfcIntent()
}
private fun setNfcIntent() {
// Create a generic PendingIntent that will be delivered to this activity. The NFC stack will fill
// in the intent with the details of the discovered tag before delivering it to this activity.
mPendingIntent = PendingIntent.getActivity(this, 0, Intent(
applicationContext, javaClass)
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0)
val tagDetected = IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
writeTagFilters = arrayOf(tagDetected)
mTechLists = arrayOf(arrayOf(
NfcV::class.java.name
))
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == ENABLE_NFC_REQUEST_CODE) {
mNfcAdapter = NfcAdapter.getDefaultAdapter(this)
if (mNfcAdapter!!.isEnabled) {
Toast.makeText(applicationContext, resources.getString(R.string.nfc_not_enabled), Toast.LENGTH_LONG).show()
finish()
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
/**
* Check the availability of NFC and BLE interfaces and let the user enable them
* if not active during the activity creation
*/
private fun checkNFC() {
if (packageManager.hasSystemFeature(PackageManager.FEATURE_NFC)) {
mNfcAdapter = NfcAdapter.getDefaultAdapter(this)
if (mNfcAdapter != null && !mNfcAdapter!!.isEnabled) {
AlertDialog.Builder(this)
.setTitle(resources.getString(R.string.dialog_nfc_not_enabled_title))
.setMessage(resources.getString(R.string.dialog_nfc_not_enabled_msg))
.setPositiveButton(resources.getString(R.string.dialog_nfc_not_enabled_positive_btn),
DialogInterface.OnClickListener { _, _ -> startActivityForResult(Intent(Settings.ACTION_NFC_SETTINGS), ENABLE_NFC_REQUEST_CODE) })
.setNegativeButton(resources.getString(R.string.dialog_nfc_not_enabled_negative_btn),
DialogInterface.OnClickListener { _, _ ->
Toast.makeText(applicationContext, resources.getString(R.string.nfc_not_enabled), Toast.LENGTH_LONG).show()
finish()
}).show()
}
} else {
Toast.makeText(applicationContext, resources.getString(R.string.nfc_not_enabled), Toast.LENGTH_LONG).show()
finish()
}
}
override fun onResume() {
super.onResume()
if (mNfcAdapter != null) {
mNfcAdapter!!.enableForegroundDispatch(this, mPendingIntent, writeTagFilters, mTechLists)
}
}
override fun onPause() {
super.onPause()
if (mNfcAdapter != null) mNfcAdapter!!.disableForegroundDispatch(this)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Log.d(TAG, "Card ID: " + Tools.byteArrayToHex(tag!!.id))
val techList = tag!!.techList
//Check that the discovered tag is a vicinity tag
if (techList[0] == "android.nfc.tech.NfcV") {
val tagUid = tag!!.id
nfcvTag = NfcV.get(tag)
//ISO/IEC 15693 tags can be operated in two modes:
// Select mode and Addressed mode.
//To work in the select mode it is needed to send a SELECT
// command at the beginning of communic.
//In the address mode, the tag UID is sent within each command.
//This application works in SELECT MODE.
val select_command: ByteArray = RFCommands.cmd_select
System.arraycopy(tagUid, 0, select_command, 2, 8)
if (nfcvTag != null) {
try {
nfcvTag!!.connect()
val select_respo = nfcvTag!!.transceive(select_command)
Log.d(TAG, "Select response: " +
Tools.byteArrayToHex(select_respo))
} catch (e: IOException) {
e.printStackTrace()
}
}
}
}
/**
* This method sends RF commands to the connected NFC-V tag,
* the command is included as parameter
* the operation will be useful in MainActivity to distinguish
* the operations in different fragments
*
* @param command
*/
fun sendCommand(command: ByteArray?): ByteArray? {
var response: ByteArray?
try {
response = nfcvTag!!.transceive(command)
Log.d(TAG, "command response: " + Tools.byteArrayToHex(response))
} catch (e: Exception) {
e.printStackTrace()
response = null
}
return response
}
companion object {
private const val ENABLE_NFC_REQUEST_CODE = 0x11
private var nfcvTag: NfcV? = null
}
}
开放类NFCActivity:AppCompativity(){
private val TAG=NFCActivity::class.java.simpleName
私有变量mNfcAdapter:NfcAdapter?=null
变量标记:标记?=null
私有变量mpendingcontent:PendingIntent?=null
私有lateinit var writeTagFilters:数组
私有lateinit var mTechLists:数组
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
checkNFC()
mNfcAdapter=NfcAdapter.getDefaultAdapter(此)
setNfcIntent()
}
私人娱乐活动{
//创建将传递到此活动的通用PendingEvent。NFC堆栈将填充
//在将发现的标记交付给此活动之前,请在意图中显示该标记的详细信息。
mPendingIntent=pendingent.getActivity(this,0,Intent(
applicationContext,javaClass)
.addFlags(意图.FLAG\u活动\u单个\u顶部),0)
val tagDetected=IntentFilter(NfcAdapter.ACTION\u TAG\u DISCOVERED)
writeTagFilters=arrayOf(已检测到标记)
mTechLists=arrayOf(arrayOf(
NfcV::class.java.name
))
}
重写activityResult(请求代码:Int,结果代码:Int,数据:Intent?){
if(requestCode==启用\u NFC\u请求\u代码){
mNfcAdapter=NfcAdapter.getDefaultAdapter(此)
如果(mNfcAdapter!!.isEnabled){
Toast.makeText(applicationContext,resources.getString(R.string.nfc\u未启用),Toast.LENGTH\u LONG.show()
完成()
}
}否则{
super.onActivityResult(请求代码、结果代码、数据)
}
}
/**
*检查NFC和BLE接口的可用性,并让用户启用它们
*如果在活动创建期间未处于活动状态
*/
私人娱乐支票NFC(){
if(packageManager.hasSystemFeature(packageManager.FEATURE\u NFC)){
mNfcAdapter=NfcAdapter.getDefaultAdapter(此)
if(mNfcAdapter!=null&&!mNfcAdapter!!.isEnabled){
AlertDialog.Builder(此)
.setTitle(resources.getString(R.string.dialog\u nfc\u未启用\u title))
.setMessage(resources.getString(R.string.dialog\u nfc\u not\u enabled\u msg))
.setPositiveButton(resources.getString(R.string.dialog\u nfc\u未启用\u positive\u btn),
DialogInterface.OnClickListener{{{,{->startActivityForResult(意图(设置.动作\u NFC\u设置),启用\u NFC\u请求\u代码)})
.setNegativeButton(resources.getString(R.string.dialog\u nfc\u未启用\u negative\u btn),
DialogInterface.OnClickListener{{{,{->
Toast.makeText(applicationContext,resources.getString(R.string.nfc\u未启用),Toast.LENGTH\u LONG.show()
完成()
}).show()
}
}否则{
Toast.makeText(applicationContext,resources.getString(R.string.nfc\u未启用),Toast.LENGTH\u LONG.show()
完成()
}
}
重写onResume(){
super.onResume()
if(mNfcAdapter!=null){
mNfcAdapter!!.enableForegroundDispatch(this、mpendingcontent、writeTagFilters、mtechlist)
}
}
覆盖暂停(){
super.onPause()
如果(mNfcAdapter!=null)mNfcAdapter!!.disableForegroundDispatch(此)
}
覆盖Wintent(意图:意图){
super.onNewIntent(意图)
tag=intent.getParcelableExtra(NfcAdapter.EXTRA_标记)
Log.d(标签,“卡ID:+Tools.bytearraythex(标签!!.ID))
val techList=tag!!.techList
//检查发现的标签是否为邻近标签
if(techList[0]=“android.nfc.tech.NfcV”){
val tagUid=tag!!.id
nfcvTag=NfcV.get(标记)
//ISO/IEC 15693标签可在两种模式下操作:
//选择模式和寻址模式。
//要在select模式下工作,需要发送select命令
//在通讯开始时发出命令。
//在地址模式下,标记UID在每个命令中发送。
//此应用程序在选择模式下工作。
val select_命令:ByteArray=RFCommands.cmd_select
System.arraycopy(tagUid,0,select_命令,2,8)
if(nfcvTag!=null){
试一试{
nfcvTag!!.connect()
val select\u respo=nfcvTag!!.收发器(select\u命令)
Log.d(标记“选择响应:”+
工具。byteArrayToHex(选择响应)
}捕获(e:IOException){
e、 printStackTrace()
}
}
}
}
/**
*此方法向连接的NFC-V标签发送RF命令,
*该命令作为参数包含在内
*该操作将有助于在MainActivity中进行区分
*不同片段中的操作
*
*@param命令
*