Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用自定义意图操作仅在特定应用程序上下文中启动活动_Android_Android Intent_Android Activity_Intentfilter_Android Intent Chooser - Fatal编程技术网

Android 使用自定义意图操作仅在特定应用程序上下文中启动活动

Android 使用自定义意图操作仅在特定应用程序上下文中启动活动,android,android-intent,android-activity,intentfilter,android-intent-chooser,Android,Android Intent,Android Activity,Intentfilter,Android Intent Chooser,我需要使用意图过滤器指定我的登录活动: <activity android:name=".view.LoginActivity" android:label="@string/app_name"> <intent-filter> <action android:name="com.example.sdk.LOGIN" /> <category andr

我需要使用意图过滤器指定我的登录活动:

    <activity
        android:name=".view.LoginActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="com.example.sdk.LOGIN" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
有可能在同一设备上同时安装两个或多个依赖同一SDK的应用程序。如果我理解正确,在这种情况下,在这些应用程序中的每个应用程序中,“活动开始”都会启动一个随机登录活动(应用程序a中的调用可能会启动应用程序B的登录)

  • 我对自定义意图过滤器工作原理的理解正确吗
  • 有没有办法告诉应用程序a中的调用只使用应用程序a中的意图过滤器声明
  • 我们也欢迎关于重用登录相关逻辑(不依赖意图过滤器)的替代方法的建议

    在这种情况下,在每个应用程序中,“活动开始”将启动一个随机登录活动

    不完全是这样。发件人:

    如果只有一个应用程序可以处理它,那么该应用程序会立即打开并给出相应的意图。如果多个活动接受该意图,系统将显示一个对话框,以便用户选择要使用的应用程序

    关于你的第二个问题:

    有没有办法告诉应用程序a中的调用只使用应用程序a中的意图过滤器声明

    我假设您无法使用显式意图启动活动,因为您无法知道库模块中客户端的活动名称


    noAPI,它将为您提供活动类,通过其
    intent-filter
    属性进行过滤<代码>PackageManagerAPI无法提供帮助。这意味着您无法获取活动的类实例来显式启动活动。这反过来意味着,你唯一的方法就是隐式地启动活动,正如前面所说的,它将以对话框提示。

    我找到了一种实现我想要的方法

    基本上,我不会在我的库中硬编码包,而是使用以下命令从库中启动登录活动:

    private static final String INTENT_ACTION_PATTERN = "%s.LOGIN";
    public void startLoginActivity() {
        Intent intent = new Intent();
        String intentAction = String.format(INTENT_ACTION_PATTERN, mContext.getPackageName());
        intent.setAction(intentAction);
        mContext.startActivity(intent);
    }
    
    我将使用一个约定,我将始终定义自定义意图过滤器以匹配我的应用程序包:

    <activity
        android:name=".view.LoginActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="com.example.myapp.LOGIN" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    
      Intent intent = new Intent("test_action_that_should_be_unique");
      startActivity(intent);
    

    这些是我为实现这一目标而采取的步骤:

  • 在清单中定义自定义意图过滤器
  • 在活动内部(您要启动的活动)覆盖onCreateonNewIntent
  • 通过创建另一个启动自定义意图的应用程序进行测试
  • 清单示例:

    <activity
       android:name="com.test.MainActivity">
       <intent-filter>
           <action android:name="test_action_that_should_be_unique"></action>
           <category android:name="android.intent.category.DEFAULT"></category>
       </intent-filter>
    </activity>
    
    从其他应用程序测试新的自定义意图:

    <activity
        android:name=".view.LoginActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="com.example.myapp.LOGIN" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    
      Intent intent = new Intent("test_action_that_should_be_unique");
      startActivity(intent);
    
    • 场外检查上述意图是否为空:

      PackageManager PackageManager=getActivity().getPackageManager(); if(intent.resolveActivity(packageManager)!=null){ 星触觉(意向); }


    我认为更好的解决方案是在
    AndroidManifest
    部分使用
    属性。客户机可以在此指定任何值,然后可以在库中读取它。因此,您的客户机将指定其
    LoginActivity
    的类名,您将使用该类名通过显式意图启动它

    客户端应用程序中的AndroidManifest
    对话框很不方便,因为活动将在令牌过期时启动(这绝对不是用户获得选择器对话框的自然事件),我找到了一种解决任务的方法。。。您可以在我的回答中查看我如何不完全理解您的建议-我如何区分两个
    MainActivity
    类(来自两个应用程序)Boris,您在库中定义了startLoginActivity?每个应用程序中都有不同的目的过滤器?@RonakMehtayup@BorisStrandjev,你能帮忙吗?我使用
    IntentFilter=newintentfilter(Intent.ActionTimeTick),但自定义操作的筛选器看起来如何?@AlexanderGorg此处使用的构造函数使用字符串作为参数。在这里,您可以使用系统常量中的预配置值,该值等于
    android.intent.action.TIME\u TICK
    ,但也可以直接使用
    “com.example.myapp.LOGIN”
    <application ...>
        ...
        <meta-data android:name="com.example.sdk.LOGIN_ACTIVITY" android:value=".view.LoginActivity" />
    </application>
    
    public void startLoginActivity(Context context) {
        String packageName = context.getPackageName();
    
        PackageManager pm = context.getPackageManager();
        ApplicationInfo appInfo = pm.getApplicationInfo(packageName, PackgeManager.GET_META_DATA);
        Bundle data = appInfo.metaData;
    
        String activityName = data.getString("com.example.sdk.LOGIN_ACTIVITY");
        if (activityName == null || activityName.isEmpty()) {
            return;
        }
        ComponentName component = ComponentName.createRelative(packageName, activityName);
        Intent intent = new Intent().setComponent(component);
    
        context.startActivity(intent);
    }