Android의 다른 애플리케이션에서 활동을 시작하는 방법


478

내 Android 응용 프로그램에서 설치된 패키지를 시작하고 싶습니다. 나는 의도를 사용하는 것이 가능하다고 가정하지만 그것을 수행하는 방법을 찾지 못했습니다. 정보를 찾을 수있는 링크가 있습니까?


2
첫 번째 앱에서 두 번째 앱을 연 다음 두 번째 앱의 아이콘을 직접 클릭하면 바람직하지 않은 두 개의 앱 인스턴스가 표시됩니다.
Radhey

답변:


707

기본 활동을 모르는 경우 패키지 이름을 사용하여 응용 프로그램을 시작할 수 있습니다.

Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) { 
    startActivity(launchIntent);//null pointer check in case package name was not found
}

5
이것이 작동하지 않는 이유는 무엇입니까? 나는 적어도 작동하지 않았다.
Simon Forsberg

22
새로운 Intent를 시작합니다. 백그라운드에있는 응용 프로그램을 다시 시작하는 것은 어떻습니까?
Salil Dua

3
@andep : 내가 만든 두 개의 응용 프로그램 사이에서 테스트했을 때 잘 작동했습니다. 패키지 이름을 알고 나면 이것이 항상 작동하거나 누군가 매니페스트 또는 어딘가에서 앱을 시작하지 못하게 할 수 있습니까?
레너드 피한

2
@ Leonard : 첫 번째 인상은 패키지 이름이 공개되어 모든 앱이 읽을 수 있기 때문에 항상 작동해야한다는 것입니다. 앱에서 나는 그것이 어디에서 호출되었는지 알 수 없지만 앱은 서비스를 통해 주요 활동을 통해 호출 할 수 없다고 결정할 수 있습니다.
andep

1
예, null을 반환 할 수 있습니다. "현재 구현은 먼저 카테고리의 주요 활동을 찾은 CATEGORY_INFO후 다음 카테고리의 주요 활동을 찾습니다CATEGORY_LAUNCHER . 둘 중 하나도 발견되지 않으면 널을 리턴합니다. "
quietmint

239

나는 이것이 대답되었다는 것을 알고 있지만 여기에 비슷한 것을 구현 한 방법이 있습니다.

Intent intent = getPackageManager().getLaunchIntentForPackage("com.package.name");
if (intent != null) {
    // We found the activity now start the activity
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
} else {
    // Bring user to the market or let them choose an app?
    intent = new Intent(Intent.ACTION_VIEW);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setData(Uri.parse("market://details?id=" + "com.package.name"));
    startActivity(intent);
}

더 나은 방법은 다음과 같습니다.

public void startNewActivity(Context context, String packageName) {
    Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    if (intent != null) {
        // We found the activity now start the activity
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    } else {
        // Bring user to the market or let them choose an app?
        intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setData(Uri.parse("market://details?id=" + packageName));
        context.startActivity(intent);
    }
}

중복 코드가 제거되었습니다.

public void startNewActivity(Context context, String packageName) {
    Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    if (intent == null) {
        // Bring user to the market or let them choose an app?
        intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("market://details?id=" + packageName));
    }
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
}

8
Facebook 또는 Twitter 프로필에 대한 의도를 시작할 때 문제가 발생했습니다. 그들은 새로운 활동 대신 내 앱에서 열었습니다. FLAG_ACTIVITY_NEW_TASK를 추가하면 문제가 해결되었습니다. 감사!
Harry

4
문제 없어요! 나는 아주 비슷한 문제를 겪고있었습니다
Jared Burrows

1
이 방법은 저에게 효과적이지만 때로는 새로운 응용 프로그램이 열려 있고 호출 활동이 여전히 전경입니다. 어떤 아이디어를 수정하는 방법?
lgdroid57

instant-app에서이를 수행 할 수있는 방법이 있습니까?
Mahdi

릴리스 버전에서만 작동합니다. 디버그 앱을 열려고하면 의도는 null입니다.
RexSplode

152

해결책을 찾았습니다. 응용 프로그램의 매니페스트 파일에서 패키지 이름 com.package.address와 시작하려는 주요 활동의 이름을 찾았습니다. MainActivity 다음 코드는이 응용 프로그램을 시작합니다.

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);

8
나는 예외 '복용량 당신의 Manifest.xml에 활동을 선언'
itzhar

이렇게하면 내 매니페스트에서 활동을 선언해야한다는 예외가 반환되지만 외부 앱입니다!
JJ Ab

백그라운드에서 실행하는 방법? 두 번째로 불리는 응용 프로그램은 화면에 표시되지 않지만 onCreated () 메서드를 실행합니다.
Dr.jacky

인스턴트 앱에서 시도 할 때이 오류가 발생합니다. 활동 의도를 시작할 수 없음
Mahdi

@Bastian 다른 앱을 열기 위해 현재 앱을 닫는 방법은 무엇입니까?
Arnold Brown

18
// in onCreate method
String appName = "Gmail";
String packageName = "com.google.android.gm";
openApp(context, appName, packageName);

public static void openApp(Context context, String appName, String packageName) {
    if (isAppInstalled(context, packageName))
        if (isAppEnabled(context, packageName))
            context.startActivity(context.getPackageManager().getLaunchIntentForPackage(packageName));
        else Toast.makeText(context, appName + " app is not enabled.", Toast.LENGTH_SHORT).show();
    else Toast.makeText(context, appName + " app is not installed.", Toast.LENGTH_SHORT).show();
}

private static boolean isAppInstalled(Context context, String packageName) {
    PackageManager pm = context.getPackageManager();
    try {
        pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
        return true;
    } catch (PackageManager.NameNotFoundException ignored) {
    }
    return false;
}

private static boolean isAppEnabled(Context context, String packageName) {
    boolean appStatus = false;
    try {
        ApplicationInfo ai = context.getPackageManager().getApplicationInfo(packageName, 0);
        if (ai != null) {
            appStatus = ai.enabled;
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    return appStatus;
}

17

누군가가 유용하다고 생각하는 경우 내 앱에서 바 / QR 코드 스캐너를 시작하는 예는 다음과 같습니다.

Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.setPackage("com.google.zxing.client.android");

try 
{
    startActivityForResult(intent, SCAN_REQUEST_CODE);
} 
catch (ActivityNotFoundException e) 
{
    //implement prompt dialog asking user to download the package
    AlertDialog.Builder downloadDialog = new AlertDialog.Builder(this);
    downloadDialog.setTitle(stringTitle);
    downloadDialog.setMessage(stringMessage);
    downloadDialog.setPositiveButton("yes",
            new DialogInterface.OnClickListener() 
            {
                public void onClick(DialogInterface dialogInterface, int i) 
                {
                    Uri uri = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
                    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                    try
                    {
                        myActivity.this.startActivity(intent);
                    }
                    catch (ActivityNotFoundException e)
                    {
                        Dialogs.this.showAlert("ERROR", "Google Play Market not found!");
                    }
                }
            });
    downloadDialog.setNegativeButton("no",
            new DialogInterface.OnClickListener() 
            {
                public void onClick(DialogInterface dialog, int i) 
                {
                    dialog.dismiss();
                }
            });
    downloadDialog.show();
}

13

의견에 따라 편집

의견에서 제안한 바와 같이 일부 버전에서는 발생하는 예외가 다를 수 있습니다.

따라서 아래 솔루션은 약간 수정되었습니다.

Intent launchIntent = null;
try{
   launchIntent = getPackageManager().getLaunchIntentForPackage("applicationId");
} catch (Exception ignored) {}

if(launchIntent == null){
    startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")));
} else {
    startActivity(launchIntent);
}

원래 답변

잘 대답했지만 앱이 설치되지 않은 경우 처리하는 매우 간단한 구현이 있습니다. 나는 이것을 이렇게한다

try{
    startActivity(getPackageManager().getLaunchIntentForPackage("applicationId"));
} catch (PackageManager.NameNotFoundException e) {
    startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")));
}

"applicationId"를 com.google.maps 등과 같이 열려고하는 패키지로 바꿉니다.


PackageManager.getLaunchIntentForPackage(...)패키지 이름이 인식되지 않는 경우 방법 NULL을 반환합니다. 던지지 않습니다 PackageManager.NameNotFoundException. 여기를 참조 하십시오 .
Adil Hussain

방금 startActivity(null)Android 10 에뮬레이터에서 시도했지만 a NullPointerException가 아닌 a가 발생 PackageManager.NameNotFoundException합니다.
Adil Hussain

내 노트 7에서는 의도 한대로 정확하게 작동합니다.
mayank1513

startActivity(Intent intent)null이 주어지면 메소드 의 의도 된 동작은 Intent무엇이며 어떻게 말합니까? Android 개발자의 설명서 에는 ActivityNotFoundException.
Adil Hussain

- 안녕 @Adil 당신은 도움이 내게이 질문에 기쁘게 할 수 stackoverflow.com/q/59615815/9640177
mayank1513

7
// check for the app if it exist in the phone it will lunch it otherwise, it will search for the app in google play app in the phone and to avoid any crash, if no google play app installed in the phone, it will search for the app in the google play store using the browser : 

 public void onLunchAnotherApp() {

        final String appPackageName = getApplicationContext().getPackageName();

        Intent intent = getPackageManager().getLaunchIntentForPackage(appPackageName);
        if (intent != null) {

            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);

        } else {

            onGoToAnotherInAppStore(intent, appPackageName);

        }

    }

    public void onGoToAnotherInAppStore(Intent intent, String appPackageName) {

        try {

            intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("market://details?id=" + appPackageName));
            startActivity(intent);

        } catch (android.content.ActivityNotFoundException anfe) {

            intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("http://play.google.com/store/apps/details?id=" + appPackageName));
            startActivity(intent);

        }

    }

uri.parse 메소드에 문자 제한이 있습니까?
API

7

다른 응용 프로그램의 특정 활동을 열려면 이것을 사용할 수 있습니다.

Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try 
{
    startActivity(intent)
}catch(ActivityNotFoundException e){
    Toast.makeText(context,"Activity Not Found",Toast.LENGTH_SHORT).show()
}

토스트를 표시하는 대신 다른 응용 프로그램이 필요한 경우 대화 상자를 표시 할 수 있습니다. 대화 상자를 사용하면 사용자가 Play-Store로 이동하여 필요한 응용 프로그램을 다운로드 할 수 있습니다.


com.android.settings.fuelgauge.PowerUsageSummary단지입니다 활동 별명com.android.settings.Settings$PowerUsageSummaryActivity, 그리고 그것은 한 안드로이드 파이에서 제거 나는이 대답 정장 파이를 만들 수있는 편집 summitted 있도록. 참고는 이전 버전과도 호환 것으로, af9252849fd94c1f2859c56a4010900ea38a607e 등 2011년 11월 10일에 AOSP 커밋 참조
주말

3

설치된 패키지가 반응하는 데이터와 작업을 알고 있으면 시작하기 전에 이러한 정보를 의도 인스턴스에 추가해야합니다.

다른 앱의 AndroidManifest에 액세스 할 수 있으면 필요한 정보를 모두 볼 수 있습니다.


1
답장을 보내 주셔서 감사합니다. 예, 다른 응용 프로그램의 AndroidManifest가 있습니다. 내가 지금하려고하는 것은 다음 코드입니다. Intent intent = new Intent (Intent.ACTION_MAIN); intent.setComponent (new ComponentName ( "com.package", ". MainActivity")); startActivity (의도); 그러나 이런 식으로 작동하지 않습니다. 좀 더 정확한 링크를 줄 수 있습니까?
Bastian

1
"startActivity ..."줄에서 응용 프로그램이 충돌합니다. 응용 프로그램이 예기치 않게 중지되었습니다. 탄원은 다시 시도하십시오. LogCat에서 오류를 어디에서 볼 수 있습니까?
Bastian

5
구성 요소를 설정할 때 클래스 대신 정규화 된 클래스 이름의 이름을 지정해야합니다. intent.setComponent (new ComponentName ( "com.package", "com.package.MainActivity")) intent .setComponent (new ComponentName ( "com.package", ". MainActivity"))
Bastian

1
알아두면 좋은 점 ... 일식에서 LogCat을 찾을 수 있습니다 : 창>보기 표시> 기타, Android> Logcat
WarrenFaith

@WarrenFaith stackoverflow.com/questions/52335402/…에 대한 지원이 필요합니다… 도와주세요.
user158

2

다음과 같이 새 활동을 시작하는 단계 :

1. 포장 의도를 얻으십시오

2.intent가 null 인 경우 사용자를 playstore로 리디렉션

의도가 null 공개 활동이 아닌 경우

public void launchNewActivity(Context context, String packageName) {
    Intent intent = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.CUPCAKE) {
        intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    }
    if (intent == null) {
        try {
            intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("market://details?id=" + packageName));
            context.startActivity(intent);
        } catch (android.content.ActivityNotFoundException anfe) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + packageName)));
        }
    } else {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }
}

2

다음을 사용하여 앱의 활동을 시작할 수 있습니다 Intent.setClassName문서에 따라 .

예를 들면 :

val activityName = "com.google.android.apps.muzei.MuzeiActivity" // target activity name
val packageName = "net.nurik.roman.muzei" // target package's name
val intent = Intent().setClassName(packageName, activityName)
startActivity(intent)

현재 앱 외부에서 열려면 인 텐트를 시작하기 전에이 플래그를 추가하십시오.

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

관련 답변은 여기


pls C ++로 작성하는 방법.
GeneCode

1
@GeneCode stackoverflow.com/a/22436147/8608146 은 이전에 안드로이드에서 c ++ 라이브러리로 작업 한 적이 없었습니다.
Phani Rithvij

1
private fun openOtherApp() {
        val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
        startActivity(sendIntent)
        finishAffinity()
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.