可以通过 NFC 意图阻止应用程序从应用程序内启动吗?
Possible to prevent app launch by NFC intent from within an app?
我有一个应用程序,其要求是在检测到非 NDEF NFC 标签时启动它,所以我在主 activity 上使用 TECH_DISCOVERED
过滤器来执行此操作:
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter>
这很好用,但是有些用户抱怨他们的 phone 保护套兼作信用卡/智能卡的持有人,因此当他们关闭 phone 保护套时应用程序无意中启动。这些用户不希望必须禁用设备 NFC 设置(并且不能以编程方式完成)所以我的问题是:是否可以通过 NFC intent 从该应用程序中以编程方式停止应用程序启动?
我能想到的最好的主意是让 NFC intent 启动一个非 UI Activity(不调用 setContentView
)并进行此检查如果已经设置了一些持久标志(通过主 activity 中的 UI 控件)并且如果设置了标志,则不要启动主 activity。
有easier/more优雅的解决方案吗?
应用程序可以简单地尝试检查 "discovered" 标签是否属于该应用程序(即数据结构符合预期,相应的 TagType 符合预期),如果不属于则再次停止。是否让用户看到它取决于您...
我的解决方案是通过 NFC intent 启动无头(不可见)activity 并使用共享首选项(通过主 activity 的 UI 开关设置)判断是否启动主activity.
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();
}
}
我有一个应用程序,其要求是在检测到非 NDEF NFC 标签时启动它,所以我在主 activity 上使用 TECH_DISCOVERED
过滤器来执行此操作:
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter>
这很好用,但是有些用户抱怨他们的 phone 保护套兼作信用卡/智能卡的持有人,因此当他们关闭 phone 保护套时应用程序无意中启动。这些用户不希望必须禁用设备 NFC 设置(并且不能以编程方式完成)所以我的问题是:是否可以通过 NFC intent 从该应用程序中以编程方式停止应用程序启动?
我能想到的最好的主意是让 NFC intent 启动一个非 UI Activity(不调用 setContentView
)并进行此检查如果已经设置了一些持久标志(通过主 activity 中的 UI 控件)并且如果设置了标志,则不要启动主 activity。
有easier/more优雅的解决方案吗?
应用程序可以简单地尝试检查 "discovered" 标签是否属于该应用程序(即数据结构符合预期,相应的 TagType 符合预期),如果不属于则再次停止。是否让用户看到它取决于您...
我的解决方案是通过 NFC intent 启动无头(不可见)activity 并使用共享首选项(通过主 activity 的 UI 开关设置)判断是否启动主activity.
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();
}
}