3

次のコードをインサービスで使用してメイン/ランチャーアクティビティを開きます。このプロジェクトをライブラリとして宣言し、このライブラリを使用する他の2つのプロジェクトを作成するまで、コードは正常に機能しました。

したがって、サービスのonStartCommandには、このコードが記述されています。

 final Notification notification = new Notification(R.drawable.ic_launcher, null, 0);   

    String notifTitle = "Service";
    String notifMessage = "Running";

    final Intent notificationIntent = new Intent(this,   MainActivity.class);
    notificationIntent.putExtra("extra", "value");
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                            | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    notificationIntent.setAction("android.intent.action.MAIN");
    notificationIntent.addCategory("android.intent.category.LAUNCHER");

    final PendingIntent contentIntent = PendingIntent
                            .getActivity(this, 0, notificationIntent,0);



    notification.setLatestEventInfo(this, notifTitle, notifMessage, contentIntent);     
    startForeground(17, notification);

MainActivity.classはライブラリの一部であり、このライブラリを使用する2つのプロジェクトには、ライブラリのMainActivityを拡張するメインアクティビティMainActivityA、MainActivityBがあります。

問題は、サービスの通知をクリックすると、MainActivityAまたはMainActivityBが起動されるはずですが、今は何も起こりませんが、以前はライブラリがプロジェクト自体であったときに機能していました

どんなアイデアもたくさん評価されるでしょう、

ありがとうございました、

4

4 に答える 4

1

あなたはあなたの意図をハードコーディングしています

final Intent notificationIntent = new Intent(this,   MainActivity.class);

MainActivityA.classまたはMainActivityB.classではなくMainActivity.classを起動します。サービスに正しいクラスを渡すか、インテントをより一般的なものに変更して、インテントフレームワークにアクティビティ(アプリに固有の可能性があります)を検出させる必要があります。

私はインテントフィルターについて何かを書いている最中だったが、@smith324は私をそれに打ち負かした。

次のような文字列リソースではなく、メタデータの使用を検討します。

<meta-data android:name="com.foo.service.LaunchName" android:value="com.foo.MainActivityA"></meta-data>

これにより、ライブラリを追加した場合のサードパーティの文字列名の衝突が回避され、ユーザーの国際化/翻訳が必要になる可能性があるものではなく、クラスの配線に適しているため、開発者にとって文字列ファイルがクリーンに保たれます。

参照:Androidマニフェストファイルにユーザー定義のプロパティ/値を追加するにはどうすればよいですか?

于 2012-11-26T04:25:18.357 に答える
1

これを行うには、いくつかの方法があります。

マニフェストでアクティビティに対してインテントフィルターを宣言し、インテントをブロードキャストすることもできますが、ユーザーが両方のバージョンをデバイスにインストールしている場合、これは問題になる可能性があります。(サポートライブラリには、ドキュメントの代わりに使用できるローカルブロードキャストがあります)

個人的には、Androidのリソースシステムを使用して、クラス名を動的にロードします。インテントを使用すると、コンポーネント名を設定できます。これは、ハードコードされた参照をアクティビティのクラスに指定するのと同じです。

Intent i = new Intent();
String mPackage = ctx.getPackageName();
String mClass = ctx.getResources().getString(R.string.notification_class_name);
i.setComponent(new ComponentName(mPackage,mPackage+mClass));

ライブラリプロジェクトの値は、それらを使用するプロジェクトによって上書きされる可能性があるため、これらのプロジェクトの両方で、そのアプリの通知アクティビティに対応する値がstrings.xmlにあります。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="notification_class_name">.MainActivityA</string>
</resources>

次に、このインテントをpendingIntentで使用すると、現在のアプリケーション内でアクティビティが開きます。

于 2012-11-26T04:52:01.097 に答える
1

これは古い質問ですが、自分で問題を解決しようとしているときにこれに出くわしました。文字列を構成したり、パラメーターを渡したりせずに、これを行うためのより簡単な方法を見つけました。

String packageName = getPackageName();
Intent notificationIntent = getPackageManager().getLaunchIntentForPackage(packageName);

これで、エクストラなどを追加できるインテントができました。

于 2013-07-28T02:14:51.660 に答える
0

ランチャーアクティビティを取得するには、次の方法があります。

public static Class<?> GetLauncherActivity(Context context)
    {
        String packageName = context.getPackageName();
        Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
        String className = launchIntent.getComponent().getClassName();
        try
        {
            return Class.forName(className);
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
            return null;
        }
    }
于 2015-03-01T08:15:14.910 に答える