【问题标题】:Possible to prevent app launch by NFC intent from within an app?可以防止应用程序内通过 NFC 意图启动应用程序吗?
【发布时间】:2017-09-12 08:41:08
【问题描述】:

我有一个应用程序,其要求是在检测到非 NDEF NFC 标签时启动它,所以我在我的主要活动中使用TECH_DISCOVERED 过滤器来执行此操作:

<intent-filter>
    <action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter>

这很好用,但是一些用户抱怨他们的手机壳兼作信用卡/智能卡的支架,因此当他们合上手机壳时,应用程序会意外启动。这些用户不想禁用设备 NFC 设置(这不能以编程方式完成),所以我的问题是:是否可以通过 NFC 意图从该应用程序内以编程方式停止应用程序启动?

我能想出的最好办法是让 NFC 意图启动一个非 UI 活动(不调用 setContentView 的活动)并检查是否设置了某些持久标志(通过 UI 控件在主要活动中),如果设置了标志,则不要启动主要活动。

有没有更简单/更优雅的解决方案?

【问题讨论】:

  • 您是否要求在检测到任何非 NDEF 标签时启动?还是特定技术类型的标签?
  • 这是一种特殊的标签类型(由于 NDA 无法准确指定),即 NfcA(14443-3/4 A 型)。但是,我需要能够在检测目标标签类型以及非目标标签时选择性地停止它启动应用程序。

标签: android nfc intentfilter


【解决方案1】:

应用程序可以简单地尝试检查“发现”标签是否属于应用程序(即数据结构是否符合预期,或者 TagType 是否符合预期),如果没有再次停止。是否让用户看到它取决于您...

【讨论】:

    【解决方案2】:

    我对此的解决方案是通过 NFC 意图启动无头(不可见)活动,并使用共享偏好(由 UI 开关通过主活动设置)来确定是否启动主活动。

    AndroidManifest.xml:

    <activity android:name="com.mypackage.NFCLaunchActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar">
        <intent-filter>
            <action android:name="android.nfc.action.TECH_DISCOVERED" />
        </intent-filter>
        <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" />
    </activity>
    

    res/nfc_tech_filter.xml:

    <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
        <tech-list>
            <tech>android.nfc.tech.NfcA</tech>
        </tech-list>
    </resources>
    

    MainActivity.java:

    public static String SETTINGS_NAME = "settings";
    public static String shouldLaunchByNFC = "launchWithNfc";
    
    // Call on changing UI state
    protected void setShouldLaunchByNFC(boolean enableLaunch) {
        setSettingBoolean(this, shouldLaunchByNFC, enableLaunch);
    }
    
    // Call to set initial UI state
    protected boolean getShouldLaunchByNFC() {
        return getSettingBoolean(this, shouldLaunchByNFC, true);
    }
    
    public static void setSettingBoolean(Activity activity, String name, boolean value){
        SharedPreferences settings = activity.getSharedPreferences(SETTINGS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean(name, value);
        editor.commit();
    }
    
    public static boolean getSettingBoolean(Activity activity, String name, boolean defaultValue){
        SharedPreferences settings = activity.getSharedPreferences(SETTINGS_NAME, MODE_PRIVATE);
        return settings.getBoolean(name, defaultValue);
    }
    

    NFCLaunchActivity.java:

    import static com.mypackage.MainActivity.getSettingBoolean;
    import static com.mypackage.MainActivity.shouldLaunchByNFC;
    
    public class NFCLaunchActivity extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // setContentView explicitly omitted
    
            boolean launchWithNfc = getSettingBoolean(this, shouldLaunchByNFC, true);
            if(launchWithNfc){
                Context context = this.getApplicationContext();
                Intent intent = new Intent();
                intent.setClassName(context, context.getPackageName() + ".MainActivity");
                context.startActivity(intent);
            }
            finish();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-06
      • 2017-09-13
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多