Java 在我自己的应用程序中启动另一个Android应用程序的服务

Java 在我自己的应用程序中启动另一个Android应用程序的服务,java,android,android-studio,android-intent,android-service,Java,Android,Android Studio,Android Intent,Android Service,我正在用am startservice从shell运行一个android应用程序服务。一切正常 am startservice -a com.anotherdeveloper.app.SERVICE --ef a 1 --ef b 2 我想知道是否有可能在没有开发人员的情况下启动另一个android应用程序的服务? 根据此链接,有可能: 但我不太明白怎么做 这是我在main活动中使用的代码: Intent intent = new Intent(); intent.setComponent(

我正在用
am startservice
从shell运行一个android应用程序服务。一切正常

am startservice -a com.anotherdeveloper.app.SERVICE --ef a 1 --ef b 2
我想知道是否有可能在没有开发人员的情况下启动另一个android应用程序的服务? 根据此链接,有可能:

但我不太明白怎么做

这是我在
main活动中使用的代码

Intent intent = new Intent();
intent.setComponent(new ComponentName("com.anotherdeveloper.app", "com.anotherdeveloper.app.SERVICE"));
ComponentName c = getApplicationContext().startForegroundService(intent);
AndroidManifest.xml
中,我添加了以下内容:

  <service
        android:name="com.anotherdeveloper.app.SERVICE"
        android:enabled="true"
        android:exported="true" />
这就是
AndroidManifest.xml
中的服务:

<service name="com.anotherdeveloper.app.General">
  <intent-filter>
    <action name="com.anotherdeveloper.app.SERVICE"/>
  </intent-filter>
  <intent-filter>
    <action name="com.anotherdeveloper.app.SERVICE_ALT"/>
  </intent-filter>
  <intent-filter>
    <action name="com.anotherdeveloper.app.TERMINATE"/>
  </intent-filter>
</service>


简短回答:这完全取决于第三方的决定(服务创建者在相应的
android:exported
中写了什么)


此处有更多详细信息:

在评论中展开您的问题:

  • 是的,如果服务被导出(你说是的),你可以启动它,所以它应该可以工作

  • 要通过Intent传递参数,需要使用“Extras”。这类似于您在
    adb shell am
    中使用的
    -e
    参数

  • 您将获得许多选项(每种类型),而不是XXX,例如:

    int value = 1;
    i.putExtra("Key", value)
    
    // or
    
    String value = "X"
    i.putExtra("Key", value)
    
    // or
    
    boolean value = true;
    i.putExtra("Key", value)
    
    它们都能工作(当然,钥匙是独一无二的)

    或者,您可以传递包含束的

            Bundle b = new Bundle();
            b.putString("x", "value");
            b.putInt("x", 1);
            b.putBoolean("x", true);
    
            Intent i = new Intent();
            i.putExtra("theBundle", b);
    
    本质上,这一切都很像Google/Java,一致性不是关键

    (当然,如果你传递了一个包,接收者必须知道这一点,这样它就可以从附加中“获取包”,然后提取每个键/值

    换言之,Bundle是一个美化的字典,它支持不同的类型,所有东西都必须是可打包的,因此它是一个必须可打包的键/值存储


    意向数据大小(对于附加数据)限制为X(不记得是1mb还是什么)但是你不能仅仅序列化1TB的信息,然后通过intent将其丢弃。记住这一点。

    既然我能够从shell启动服务,这难道不意味着
    android:exported
    的值是
    true
    ,因此该服务是供外部使用的吗?如果你可以在命令行y中启动它,那么是的您可以在代码中使用它,但您确定可以在命令行中启动它吗?您的代码将其作为前台服务启动(正确),但您的命令行没有。我不认为您的命令行(指定的方式)应该可以工作。例如:
    am start foreground service com.anotherdeveloper.app/.service
    是的,我在命令行中尝试过它,它可以工作。那么可能问题是我不应该作为前台服务启动它?另外,我应该在manifest.xml中添加什么,因为它在
    android:name=“com.anotherdeveloper.app.service”上给我一个错误
    ?您不应该为了调用第三方服务而更改应用程序的清单。但是我不确定“不作为前台启动”-这取决于您的设备sdk版本(StartForegroundsService要求最小sdk为26,所以如果您的设备为21,则无法工作)非常感谢您的回答。您能检查更新的问题吗?我添加了代码和一点AndroidManifest.xml。似乎您是对的,没有导出的
    exported=“true”
    在该服务中…这非常奇怪,因为我可以从shell启动该服务,这不意味着该服务是供外部使用的吗?问题:您是否尝试进行更改
    getApplicationContext().
    这个。
    因为你已经在一个活动/上下文中了。这样行吗?我已经尝试了
    getApplicationContext().startService(intent)
    this.startService(intent)
    .Hmm好吧,我今天来看看是否能找到什么。在过去的几年里,我没有通过cmd热线启动过很多服务;这是一种通常针对某个项目的事情,在这个项目中,无论出于什么原因,你都会经常这样做,当你完成后,你再也不会接触到它。所以我想确定一下我并没有给你不好的建议。
    int value = 1;
    i.putExtra("Key", value)
    
    // or
    
    String value = "X"
    i.putExtra("Key", value)
    
    // or
    
    boolean value = true;
    i.putExtra("Key", value)
    
            Bundle b = new Bundle();
            b.putString("x", "value");
            b.putInt("x", 1);
            b.putBoolean("x", true);
    
            Intent i = new Intent();
            i.putExtra("theBundle", b);