วิธีเรียกใช้กิจกรรมจากแอปพลิเคชันอื่นใน Android


478

ฉันต้องการเปิดตัวแพ็คเกจที่ติดตั้งจากแอปพลิเคชัน Android ของฉัน ฉันคิดว่ามันเป็นไปได้ที่จะใช้ intents แต่ฉันไม่พบวิธีที่จะทำ มีลิงค์ที่จะค้นหาข้อมูลหรือไม่


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: มันทำงานได้ดีสำหรับฉันเมื่อฉันทดสอบระหว่างสองแอพที่ฉันสร้างขึ้นเอง เมื่อฉันรู้ชื่อแพคเกจจะใช้งานได้เสมอหรือมีวิธีป้องกันไม่ให้บางคนเปิดแอปของคุณ (ใน maniefest หรือที่อื่น)
Leonard Feehan

2
@ Leonard: ความประทับใจครั้งแรกของฉันที่จะต้องใช้งานได้เสมอเพราะชื่อแพคเกจเป็นสาธารณะเพื่อให้แอปใด ๆ สามารถอ่านได้ จากแอพของคุณฉันคิดว่าคุณไม่สามารถระบุได้ว่ามันถูกเรียกที่ไหน แต่แอพของคุณสามารถระบุได้ว่ามันไม่สามารถโทรผ่านกิจกรรมหลักเพียงแค่ผ่านบริการ
andep

1
ใช่สิ่งนี้สามารถคืนค่าว่างได้ "การดำเนินการลักษณะปัจจุบันครั้งแรกสำหรับกิจกรรมหลักในหมวดหมู่CATEGORY_INFOและต่อไปสำหรับกิจกรรมหลักในหมวดหมู่CATEGORY_LAUNCHER. กลับ NULL ถ้าค่าที่พบ. "
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

มีวิธีใดบ้างในการทำเช่นนี้จากแอปพลิเคชันทันที
Mahdi

ใช้งานได้เฉพาะกับรุ่นที่วางจำหน่าย หากคุณกำลังพยายามเปิดแอพดีบั๊กเจตนาจะเป็นโมฆะ
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

ฉันได้รับข้อผิดพลาดนี้เมื่อฉันลองจากแอปพลิเคชันทันที: ไม่อนุญาตให้เริ่มกิจกรรม Intent
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(...)วิธีการส่งกลับเป็นโมฆะถ้าชื่อแพคเกจไม่เป็นที่รู้จัก PackageManager.NameNotFoundExceptionมันไม่โยน ดูที่นี่
Adil Hussain

ฉันก็พยายามstartActivity(null)บน Android 10 จำลองและมันพ่นและไม่ได้เป็นNullPointerException PackageManager.NameNotFoundException
Adil Hussain

ในบันทึกย่อของฉัน 7 มันใช้งานได้ตามที่ตั้งใจไว้
mayank1513

พฤติกรรมที่ตั้งใจไว้ของstartActivity(Intent intent)วิธีการนั้นเมื่อได้รับเป็นโมฆะIntentและอะไรทำให้คุณพูดอย่างนั้น? หุ่นยนต์ที่พัฒนาเอกสาร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()
}

หากคุณต้องการแอปพลิเคชั่นอื่นแทนที่จะแสดง Toast คุณสามารถแสดงไดอะล็อก การใช้กล่องโต้ตอบคุณสามารถนำผู้ใช้ไปยัง Play-Store เพื่อดาวน์โหลดแอปพลิเคชันที่ต้องการ


com.android.settings.fuelgauge.PowerUsageSummaryเป็นเพียงนามแฝงของกิจกรรมcom.android.settings.Settings$PowerUsageSummaryActivityและมันถูกลบออกใน Android Pieดังนั้นฉันจึงสรุปการแก้ไขเพื่อให้เหมาะกับคำตอบนี้ โปรดทราบว่ามันยังเข้ากันได้กับรุ่นเก่าดู AOSP กระทำเมื่อวันที่ 10 พฤศจิกายน 2011 af9252849fd94c1f2859c56a4010900ea38a607e ฯลฯ
วันหยุดสุดสัปดาห์

3

หากคุณทราบข้อมูลและการดำเนินการของแพ็คเกจที่ติดตั้งไว้คุณควรเพิ่มข้อมูลเหล่านี้ลงในอินสแตนซ์ที่คุณต้องการก่อนเริ่ม

หากคุณสามารถเข้าถึง AndroidManifest ของแอปอื่น ๆ คุณสามารถดูข้อมูลที่จำเป็นทั้งหมดได้ที่นั่น


1
ขอบคุณสำหรับการตอบกลับ. ใช่ฉันมี AndroidManifest ของแอปพลิเคชันอื่น สิ่งที่ฉันพยายามทำตอนนี้คือรหัสต่อไปนี้: เจตนาเจตนา = เจตนาใหม่ (Intent.ACTION_MAIN); intent.setComponent (ComponentName ใหม่ ("com.package", "MainActivity")); startActivity (เจตนา); แต่ด้วยวิธีนี้มันไม่ทำงาน คุณสามารถให้ลิงค์ที่แม่นยำกว่ากับฉันได้อย่างไร
บาสเตียน

1
แอปพลิเคชันหยุดทำงานที่บรรทัด "startActivity ... ": แอปพลิเคชันหยุดโดยไม่คาดคิด โปรดลองอีกครั้ง ฉันจะดูข้อผิดพลาดใน LogCat ได้ที่ไหน
บาสเตียน

5
ฉันพบข้อผิดพลาด: เมื่อตั้งค่าคอมโพเนนต์ชื่อคลาสแบบเต็มแทนที่จะเป็นคลาสจะต้องมีชื่อ: intent.setComponent (ComponentName ใหม่ ("com.package", "com.package.MainActivity")) แทนเจตนา .setComponent (ComponentName ใหม่ ("com.package", "MainActivity"))
Bastian

1
เป็นการดีที่จะรู้ว่า ... คุณสามารถค้นหา LogCat บน eclipse: หน้าต่าง> แสดงมุมมอง> อื่น ๆ , Android> Logcat
WarrenFaith

@WarrenFaith ฉันต้องการความช่วยเหลือกับstackoverflow.com/questions/52335402/…โปรดช่วยด้วย
user158

2

ขั้นตอนในการเปิดตัวกิจกรรมใหม่ดังต่อไปนี้:

1. รับเจตนาสำหรับแพ็คเกจ

2. ถ้าเจตนาคือ null เปลี่ยนเส้นทางผู้ใช้ไปยัง playstore

3. ถ้าเจตนาไม่เป็นโมฆะกิจกรรมเปิด

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)

คำตอบที่เกี่ยวข้องที่นี่


กรุณาวิธีการเขียนใน C ++
GeneCode

1
@GeneCode stackoverflow.com/a/22436147/8608146อาจช่วยฉันไม่เคยทำงานกับ c ++ libs ใน Android มาก่อน
Phani Rithvij

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.