0

バックグラウンド サービスを開始する必要がある AIR ネイティブ拡張に取り組んでいます。

サービスを開始するさまざまな方法を試しました。

これが私の AIR Android マニフェスト セクションです (私の -app.xml ファイルから)

//AIR android manifest section
<manifest android:installLocation="auto">
    <application>
        <activity android:name=".TestActivity">
            <intent-filter>
                <action android:name=".TestActivity"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

    <service android:name=".TestService">
    <intent-filter>
        <action android:name="test.default.service"/>
    </intent-filter>
    </service>
    </application>
</manifest>

Service Class は Activity と同じパッケージにあります。アクティビティは問題なく実行され、アクティビティの onStart() メソッドで、次のメソッドを使用してサービスを開始しようとしました。

方法 1:

import android.app.Activity;

public class TestActivity extends Activity
{
    @Override
    protected void onStart()
    {
        super.onStart();
        Intent intent = new Intent("test.default.service");

        //clearly the classes are available because this compiles!
    intent.setClass(TestActivity.this, TestService.class);

        startService(intent);
    }
}

結果:

Unable to start service Intent { act=test.default.service cmp=air.com.my.company/com.my.company.TestService } U=0: not found

方法 2:

import android.app.Activity;

public class TestActivity extends Activity
{
    @Override
    protected void onStart()
    {
        super.onStart();

        //start a service with intent
        startService(new Intent("test.default.service"));
    }
}

結果:

FATAL EXCEPTION: main
java.lang.RuntimeExeption: Unable to instantiate service air.com.my.company.TestService:
java.lang.ClassNotFoundException: 
Didn't find class "air.com.my.company.TestService" on path: /data/app/air.com.my.company-1.apk

問題はその「空気」にあるようです。サービスを開始しようとすると、パッケージ名にプレフィックスが付けられます。独自のカスタム サービスを実行しているときに、このパッケージ名の混乱を回避するにはどうすればよいですか?

私はアドビのフォーラムだけでなく、スタック オーバーフローにも遭遇しましたが、この問題に対する完全な解決策を見つけることができないようです。

このトピックに触れている他の投稿がいくつかありますが、ソースを使用して実際に実行中のソリューションを提供するものはありません。

問題の原因となる余分な可動部分がないことを確認するために、これをできる限り単純なケースに切り詰めました。

AIR で実行されている拡張コンテキストから Android サービスを開始する方法に関する公式情報は役に立ちます。Adobe でさえ、この問題について口を閉ざしているようです。

4

3 に答える 3

1

パッケージ名を使用して、マニフェストの追加でサービス クラスを完全にスコープする必要があると思います。

...
<service android:name="com.my.company.TestService">

それがなければうまくいくかどうかはわかりません。通常の Android がクラスを正しく先頭に追加することは知っていますが、AIR アプリケーションは空気を取得します。問題を引き起こす可能性のあるプレフィックス。

アップデート:

私たちは実際にいくつかのネイティブ拡張機能でこれを行っているので、それが正しいことはわかっています。

完全にスコープされたクラス名でサービスを宣言すると、問題が発生しているドットの簡略表記が使用されません。ドットの短縮形を使用すると、Android はクラスがアプリケーション パッケージにあると想定します。これは AIR アプリケーションの下にあります。

air.com.my.company

あなたのやり方は、別のアプリ ID を持つ別のアプリケーションでは ANE が機能しないことを意味します!

別の AIR アプリケーションは、デフォルトで

air.com.other.company.TestService 

したがって、簡略表記のままにしておくと、このアプリケーションがサービス/アクティビティを見つけられないことを意味します。

air.com.my.company.TestService

正しい方法は、ネイティブ コードでクリーンなパッケージ名 (com.company.nativepackage など) を使用し、これを以下のようにマニフェストに含めることです。

<application>
    <activity android:name="com.company.nativepackage.TestActivity">
        <intent-filter>
            <action android:name="TestActivity"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>

    <service android:enabled="true" android:exported="true" android:name="com.company.nativepackage.TestService">    
        <intent-filter>
            <action android:name="air.com.my.company.DO_CUSTOM_ACTION"/>
        </intent-filter>
    </service>
</application>

これはどのアプリケーションでも機能し、ANE の移植性を高めることができます。それが理にかなっていることを願っています。

于 2013-02-02T23:38:03.897 に答える
0

私はこの質問を入力して回答しました。何が必要かを正確に把握するのにかなりの時間がかかり、他の多くの開発者の深刻な頭痛の種を救うことを望んでいるからです。

上に示したAndroidマニフェストは完全に問題ありません。上に示したコード(両方の方法で)は完全に問題ありません。

問題は、署名証明書とAIRアプリケーションのパッケージ名の両方にあります。

AdobeAIRネイティブ拡張機能のルール

ルール1. コード署名証明書パッケージはapp.xmlのアプリケーションIDと一致する必要があるため、証明書パッケージがcom.my.companyの場合、airアプリIDは次のようになります。<id>com.my.company</id>

ルール 2.ADTを使用してAndroidのネイティブ拡張機能をパッケージ化する場合、パッケージ名にプレフィックスが追加されるため、のようになりますair.com.my.company

Android ActivityManagerがサービスを実行しようとすると、でサービスを検索しますair.com.my.company。したがって、Serviceクラスは、Javaコード内の同じパッケージ(「air」プレフィックスを含む)に存在する必要があります。私のTestServiceクラスは次のように定義されていますair.com.my.company.TestService

そして、次のマニフェストで、それはうまく動作します!

<application>
    <activity android:name=".TestActivity">
        <intent-filter>
            <action android:name="TestActivity"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>

    <service android:enabled="true" android:exported="true" android:name=".TestService">    
        <intent-filter>
            <action android:name="air.com.my.company.DO_CUSTOM_ACTION"/>
        </intent-filter>
    </service>
</application>

そして...これが私がサービスを呼び出す方法です。

Intent intent = new Intent("air.com.my.company.DO_CUSTOM_ACTION");
intent.setClass(currentContext, TestService.class);
currentContext.startService(intent);
于 2013-02-04T17:48:29.673 に答える