【问题标题】:How do I prevent a service app from launching its ui activity when it starts?如何防止服务应用程序在启动时启动其 ui 活动?
【发布时间】:2015-01-21 22:24:50
【问题描述】:

我想从移动应用向穿戴式应用发送消息,并在穿戴式应用收到消息后显示一些 UI 活动。

我已经准备好了一切,并且已经为此工作(移动应用正在使用 Wea​​rable.MessageApi.sendMessage,而穿戴应用正在扩展 WearableListenerService)。但是我的问题是,当我运行穿戴应用程序时,用户界面会在启动时出现,我应该更改什么以便在穿戴应用程序收到来自移动设备的消息之前什么都不显示?如何防止在应用启动时创建 Activity?

清单:

   <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.DeviceDefault" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".WearMessageListenerService">
            <intent-filter>
                <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
            </intent-filter>
        </service>
    </application>

活动:

public class MainActivity extends Activity {
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i("WEAR", "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
        stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
            @Override
            public void onLayoutInflated(WatchViewStub stub) {
                mTextView = (TextView) stub.findViewById(R.id.text);
            }
        });
    }
}

服务:

public class WearMessageListenerService extends WearableListenerService {
    private static final String START_ACTIVITY = "/start_activity";
    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        Log.i("WEAR", "WearableListenerService:onMessageReceived");
        if( messageEvent.getPath().equalsIgnoreCase( START_ACTIVITY ) ) {
            Intent intent = new Intent( this, MainActivity.class );
            intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
            startActivity( intent );
        } else {
            super.onMessageReceived(messageEvent);
        }
    }
}

【问题讨论】:

  • 啊,所以我更改了配置以取消单击启动默认活动,这可以解决问题。

标签: android android-activity android-service wear-os


【解决方案1】:

清单的变化

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

您已在主Activity 中的intent-filter 中设置LAUNCHER 类别,这意味着此活动可以从启动器启动 - 在 Android Wear 上,它是按下表盘 启动“Speak now”屏幕并向下滚动至开始...。您将在那里看到“可启动”应用程序列表,根据您的描述,这也是您要避免的。

通过删除此intent-filter,您可以确保用户无法手动启动此Activity,因此启动它的唯一方法是“当 Wear 应用收到来自移动设备的消息时”,直接从您的代码。

您的最终清单应如下所示:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.DeviceDefault" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
    </activity>
    <service android:name=".WearMessageListenerService">
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
        </intent-filter>
    </service>
</application>

配置变更

如果您之前定义了“默认活动”,Android Studio 将不允许您启动应用程序。您需要点击“Edit Configuration”,然后点击“wear”模块,然后在“General”选项卡中选择“Do not launch activity”。

【讨论】:

    【解决方案2】:

    不确定这是否是执行此操作的好方法,但您可以从您的服务中额外发送一个意图。在 Activity 的 onCreate 方法上,您可以检查是否收到任何额外内容,如果没有,您的应用程序已作为启动器 Activity 启动,那么您可以使用 finish() 销毁 Activity,否则如果您收到额外内容,则意味着呼叫来自服务,您显示您必须显示的任何内容。

    【讨论】:

    • 所以没有简单的方法来指定不应在应用启动时启动 Activity?例如,通过在清单中留下一些东西?我尝试省略意图过滤器,但构建抱怨没有默认活动。我可以将类型从应用程序更改为服务或解决这个问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 2015-08-18
    • 2015-07-22
    相关资源
    最近更新 更多