onNewIntent永远不会被片段触发

时间:2018-04-08 10:57:29

标签: android android-fragments nfc onnewintent

我在使用onNewIntent方法在Fragment中工作时遇到了问题。我尝试了一切,但似乎没有任何工作。我的项目在使用活动时工作得很好但是当我切换到碎片时它停止工作。我的想法是,我想制作标签,其中一个标签写入NFC标签,其他标签将从NFC标签读取数据。这是我的Fragment代码(编写Tab):

    public class Home extends Fragment {

    NfcAdapter nfcAdapter;
    Button writebtn;
    Tag tag;
    EditText txtName1, txtName2, txtName3;

    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view,savedInstanceState);
        nfcAdapter = NfcAdapter.getDefaultAdapter(getContext());

         txtName1 = (EditText)view.findViewById(R.id.pName1);
         txtName2= (EditText)view.findViewById(R.id.pName2);
        txtName3= (EditText)view.findViewById(R.id.pName3);
        writebtn=(Button)view.findViewById(R.id.nfcWriteBtn);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View v= inflater.inflate(R.layout.home, container,false);
        return v;

    }


    @Override
    public void onResume() {
        super.onResume();

        if(nfcAdapter !=null){

            /* go to phone's nfc settings */
            if(!nfcAdapter.isEnabled()){
                showNfcSettings();
            }
            enableForegroundDispatchSystem();
        }

    }

    private void showNfcSettings() {
        Intent nfcSettingIntent = new Intent(Settings.ACTION_NFC_SETTINGS);
        startActivity(nfcSettingIntent);
    }

    @Override
    public void onPause() {
        super.onPause();

        disableForegroundDispatchSystem();
    }


    protected void onNewIntent(Intent intent) {
        System.out.print("I am here in Home");
        Log.d("my tag", "I am here now");
        Toast.makeText(getActivity(), "NfcIntent!", Toast.LENGTH_SHORT).show();
        if (intent.hasExtra(NfcAdapter.EXTRA_TAG)) {
       // if (nfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
            Toast.makeText(getActivity(), "NfcIntent!", Toast.LENGTH_SHORT).show();
            tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            writebtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    NdefMessage ndefMessage = createNdefMessage(txtName1.getText().toString(), txtName2.getText().toString(),txtName3.getText().toString());
                    writeNdefMessage(tag, ndefMessage);
                }
            });

        }

    }


    private void enableForegroundDispatchSystem() {

        Intent intent = new Intent(getActivity(), getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), 0, intent, 0);

        IntentFilter[] intentFilters = new IntentFilter[]{};

        nfcAdapter.enableForegroundDispatch(getActivity(), pendingIntent, intentFilters, null);
    }

    private void disableForegroundDispatchSystem() {
        nfcAdapter.disableForegroundDispatch(getActivity());
    }
    private void formatTag(Tag tag, NdefMessage ndefMessage) {
        try {

            NdefFormatable ndefFormatable = NdefFormatable.get(tag);

            if (ndefFormatable == null) {
                Toast.makeText(getContext(), "Tag is not ndef formatable!", Toast.LENGTH_SHORT).show();
            }

            else{
                ndefFormatable.connect();
                ndefFormatable.format(ndefMessage);
                ndefFormatable.close();
                Toast.makeText(getContext(), "Tag writen!", Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            Log.e("formatTag", e.getMessage());
        }

    }

    private void writeNdefMessage(Tag tag, NdefMessage ndefMessage) {

        try {

            if (tag == null) {
                Toast.makeText(getContext(), "Tag object cannot be null", Toast.LENGTH_SHORT).show();
                return;
            }

            Ndef ndef = Ndef.get(tag);

            if (ndef == null) {
                // format tag with the ndef format and writes the message.
                formatTag(tag, ndefMessage);
            } else {
                ndef.connect();
                if (!ndef.isWritable()) {
                    Toast.makeText(getContext(), "Tag is not writable!", Toast.LENGTH_SHORT).show();

                    ndef.close();
                    return;
                }

                ndef.writeNdefMessage(ndefMessage);
                ndef.close();

                Toast.makeText(getContext(), "Tag writen!", Toast.LENGTH_SHORT).show();

            }

        } catch (Exception e) {
            Log.e("writeNdefMessage", e.getMessage());
        }

    }


    private NdefRecord createTextRecord(String content) {
        try {
            byte[] language;
            language = Locale.getDefault().getLanguage().getBytes("UTF-8");

            final byte[] text = content.getBytes("UTF-8");
            final int languageSize = language.length;
            final int textLength = text.length;
            final ByteArrayOutputStream payload = new ByteArrayOutputStream(1 + languageSize + textLength);

            payload.write((byte) (languageSize & 0x1F));
            payload.write(language, 0, languageSize);
            payload.write(text, 0, textLength);

            return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload.toByteArray());

        } catch (UnsupportedEncodingException e) {
            Log.e("createTextRecord", e.getMessage());
        }
        return null;
    }
    private NdefMessage createNdefMessage(String content, String content2, String content3) {

        NdefRecord ndefRecord = createTextRecord(content);
        NdefRecord ndefRecord2 = createTextRecord(content2);
        NdefRecord ndefRecord3 = createTextRecord(content3);

        NdefMessage ndefMessage = new NdefMessage(new NdefRecord[]{ndefRecord, ndefRecord2, ndefRecord3});

        return ndefMessage;
    }

}

在包含选项卡的Activity中,我创建了此方法:

 public class DosisHome extends AppCompatActivity {

    protected DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mtoggle;
    NfcAdapter nfcAdapter;
    private Toolbar mtoolbar;
    Fragment fragment;
    private TextView mName;
    private SectionsPagerAdapter mSectionsPagerAdapter;
    private ViewPager mViewPager;
    private NavigationView mNavigationView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.drawer_layout);

        mtoolbar = (Toolbar) findViewById(R.id.nav_action);
        setSupportActionBar(mtoolbar);
        mNavigationView= (NavigationView)findViewById(R.id.nav_view);
        mDrawerLayout = findViewById(R.id.drawer_layout);
        mtoggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.open, R.string.close);
        mDrawerLayout.addDrawerListener(mtoggle);
        mtoggle.syncState();
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);

        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));

        tabLayout.setupWithViewPager(mViewPager);
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                switch (tab.getPosition())
                {
                    case 0:
                        mViewPager.setCurrentItem(0);
                        mtoolbar.setTitle("Home");
                        break;

                    case 1:
                        mViewPager.setCurrentItem(1);
                        mtoolbar.setTitle("Write");
                        break;

                    case 2:
                        mViewPager.setCurrentItem(2);
                        mtoolbar.setTitle("Read");
                        break;

                    case 3:
                        mViewPager.setCurrentItem(3);
                        mtoolbar.setTitle("Others");
                        break;

                    case 4:
                        mViewPager.setCurrentItem(4);
                        mtoolbar.setTitle("Alarm");
                        break;


                    default:
                        mViewPager.setCurrentItem(tab.getPosition());
                        mtoolbar.setTitle("Home APP");
                        break;
                }

            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);

        NavigationView navigationView = findViewById(R.id.nav_view);

        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                // set item as selected to persist highlight
                menuItem.setChecked(true);

                switch (menuItem.getItemId()){

                    case R.id.nav_write:
                        mViewPager.setCurrentItem(0);
                        mDrawerLayout.closeDrawers();
                        mtoolbar.setTitle("Write");
                        break;

                    case R.id.nav_read:
                        mViewPager.setCurrentItem(1);
                        mDrawerLayout.closeDrawers();
                        mtoolbar.setTitle("Read");
                        break;

                    case R.id.nav_other:
                        mViewPager.setCurrentItem(2);
                        mDrawerLayout.closeDrawers();
                        mtoolbar.setTitle("Others");
                        break;

                    case R.id.nav_alarm:
                        mViewPager.setCurrentItem(3);
                        mDrawerLayout.closeDrawers();
                        mtoolbar.setTitle("Alarm");
                        break;

                    case R.id.nav_logout:
                        FirebaseAuth.getInstance().signOut();
                        finish();
                        startActivity(new Intent(getApplicationContext(),Login.class));

                }


                // close drawer when item is tapped
                mDrawerLayout.closeDrawers();
                return true;
            }
        });

        mDrawerLayout.addDrawerListener(
                new DrawerLayout.DrawerListener() {
                    @Override
                    public void onDrawerSlide(View drawerView, float slideOffset) {
                        // Respond when the drawer's position changes
                    }

                    @Override
                    public void onDrawerOpened(View drawerView) {
                        // Respond when the drawer is opened
                    }

                    @Override
                    public void onDrawerClosed(View drawerView) {
                        // Respond when the drawer is closed
                    }

                    @Override
                    public void onDrawerStateChanged(int newState) {
                        // Respond when the drawer motion state changes
                    }
                }
        );

    }

    @Override
    public void onNewIntent(Intent intent) {
        setIntent(intent);
        super.onNewIntent(intent);
        Toast.makeText(this, "I am in TabsHome", Toast.LENGTH_SHORT).show();
        System.out.print("I am here in TabsHome");
        Log.d("my tag", "I am here");
        // Notify fragment about the new intent

       if(fragment instanceof Home){
           Log.d("my tag", "I am here");
           Home hm = (Home) fragment;
           hm.onNewIntent(intent);
        }

    }







    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_dosis_home, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.


        if(mtoggle.onOptionsItemSelected(item)){
            return true;
        }
        //noinspection SimplifiableIfStatement
        if (item.getItemId()== R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position){

                case 0:
                    Home home= new Home();
                    return home;
                case 1:
                    Writer write = new Writer();
                    return write;

                case 2:
                    Reader read= new Reader();
                    return read;

                case 3:
                    Others other= new Others();
                    return other;

                case 4:
                    Alarm alarm= new Alarm();
                    return alarm;

            }
            return null;
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 5;
        }
        /*to set text instead of icons*/
        public CharSequence getPageTitle(int position){

            return null;
        }
    }
}

我的带有标签的AndroidManifest for Activity:

   <activity android:name=".TabsHome"
        android:windowSoftInputMode="adjustPan"
        android:screenOrientation="portrait"
        android:launchMode="singleTop">

        <intent-filter>
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.LAUNCHER" />
            <action android:name="android.nfc.action.TAG_DISCOVERED" />
            <action android:name="android.nfc.action.NDEF_DISCOVERED" />


            <data android:mimeType="text/plain" />
        </intent-filter>

        <meta-data
            android:name="android.nfc.action.TECH_DISCOVERED"
            android:resource="@xml/nfc_tech_filter" />
    </activity>

我已经用解决方案研究了类似的问题但是它们似乎都不适用于我的实现。我在这里做错了什么?

5 个答案:

答案 0 :(得分:1)

在活动中执行此操作:


    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)//This will be used in NFCCardFragment
    }

在活动中调用setIntent时,在片段onResume中的方法称为automatically

这样您就可以从中获得意图:

    override fun onResume() {
        super.onResume()
        nfcAdapter?.let { adapter ->
            if (adapter.isEnabled)
                adapter.enableForegroundDispatch(
                    requireActivity(),
                    nfcPendingIntent,
                    nfcFilters,
                    nfcTechLists
                )
        }

        //this part is the point
        requireActivity().intent?.let {
        //Do whatever you want!
            resolveNFCIntent(it)
        }
    }

答案 1 :(得分:0)

onNewIntent属于Activity,因此您无法在片段中直接使用它。您可以做的是在活动到达onNewIntent时将活动数据传递给您的片段,前提是您有片段的引用。

@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
List<Fragment> allFragments = getSupportFragmentManager().getFragments();
Fragment fragment;
    for (Fragment fragment : allFragments) {
        if (fragment instanceof Home) {
            Home frgHome = (Home) fragment;
            frgHome.onNewIntent(intent);
        }
    }
}

答案 2 :(得分:0)

问题在于,您的my %h1 = h2变量永远不会被初始化,因此 <select id="getDetails" statementType="CALLABLE" parameterType="map" > {call GET_DETAILS( #{Null,javaType=String,jdbcType=VARCHAR,mode=IN}, --P_MSG_ID #{header.sourceId,javaType=String,jdbcType=VARCHAR,mode=IN}, --SC_ND . -- here I have an OUT parameter that I need to discard from the mapping . . . </select> 条件永远不会有效。

您希望将newIntent数据传递给fragment片段,该片段位于fragment instanceof Home作为第一页(即第0个索引)。因此,您可以要求Home通过ViewPager方法向您提供SectionsPagerAdapter片段。但是,如果您查看Home方法的实现,则始终使用

返回新的片段实例
getItem(int position)

所以,如果你打电话给getItem(),它会给你另一个Home Fragment实例,而不是当前正在显示的那个。因此,您需要先在我显示的case 0: Home home= new Home(); return home; 中进行一些更改。

使用以下内容更改mSectionAdapater.getItem()

SectionsPagerAdapter

现在,在您的活动中更改SectionsPagerAdapter方法:

public class SectionsPagerAdapter extends FragmentPagerAdapter {
    private List<Fragment> mFragments = new ArrayList<>();

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
        mFragments.add(new Home());
        mFragments.add(new Writer());
        mFragments.add(new Reader());
        mFragments.add(new Others());
        mFragments.add(new Alarm());
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return mFragments.size();
    }

    /*to set text instead of icons*/
    public CharSequence getPageTitle(int position) {

        return null;
    }
}

答案 3 :(得分:0)

我不确定你们是否解决了这个问题。但是,我试图通过读取NFC片段来做同样的事情,对我来说,问题是在将片段移到活动时,onNewIntent开始起作用后,片段中的意图并未在正确的时间初始化。从那里我将意图发送到要处理的片段。不知道这是否仍然有用,是否有更好的方法可以随意共享它,因为如果可能,我希望该片段完全独立于活动。

答案 4 :(得分:0)

您所能做的就是使用界面。

在“活动”中使用:

private interfaceName listener;

public void setNewIntentListner(Fragment fragmentName) {
    listener =  fragmentName;
}

 @Override
protected void onNewIntent(Intent intent) {
    if(listener != null){
    listener.newIntent(intent);
    }

    return;
}

界面:

public interface InterfaceName{
    void newIntent(Intent intent);
}

最后在您的片段中:

public class fragmentName extends Fragment implements interfaceName{

    private MainActivity mainActivity;

    @Override
    public void onStart() {
        super.onStart();
        mainActiviyt = (MainActivity)getActivity();
        mainActivity.setNewIntentListner(this);

    }
    @Override
    public void newIntent(Intent intent) {
    // here you have your intent in your fragment 
    }

}