簡體   English   中英

檢查是否安裝了應用程序 - Android

[英]Check if application is installed - Android

我正在嘗試從 Google Play 安裝應用程序。 我可以理解,在打開 Google Play 商店 URL 時,它會打開 Google Play,當我按下后退按鈕時,活動恢復。

Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(appURL));
marketIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(marketIntent);

當我回到活動中時,我嘗試調用此onResume()來檢查應用程序是否已安裝,但我收到錯誤消息:

@Override
protected void onResume() {
    super.onResume();
    boolean installed = false;
    while (!installed) {
        installed  =   appInstalledOrNot(APPPACKAGE);
        if (installed) {
             Toast.makeText(this, "App installed", Toast.LENGTH_SHORT).show();
        }
    }
}

private boolean appInstalledOrNot(String uri) {
  PackageManager pm = getPackageManager();
  boolean app_installed = false;
  try {
      pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
      app_installed = true;
  }
  catch (PackageManager.NameNotFoundException e) {
      app_installed = false;
  }
  return app_installed ;
}

錯誤如下:

E / AndroidRuntime(796):java.lang.RuntimeException:無法啟動活動ComponentInfo {com.example.appinstaller/com.example.appinstaller.MainActivity}:android.content.ActivityNotFoundException:找不到處理Intent的活動{act = android .intent.action.VIEW dat=market://details?id=com.package.name flg=0x40080000 }

我猜活動是onPause() 有沒有更好的方法來實現它? 我正在嘗試檢查該應用程序是否已完成安裝。

試試這個:

private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    try {
        packageManager.getPackageInfo(packageName, 0);
        return true;
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

它嘗試獲取有關您傳入的名稱的包的信息。如果失敗,如果拋出NameNotFoundException ,則意味着沒有安裝具有該名稱的包,因此我們返回false

請注意,我們傳入的是PackageManager而不是Context ,因此該方法的使用更加靈活,並且不會違反Demeter 定律 只要您有PackageManager實例,您就可以在不訪問Context實例的情況下使用該方法。

像這樣使用它:

public void someMethod() {
    // ...
    
    PackageManager pm = context.getPackageManager();
    boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);
    
    // ...
}

注意:從 Android 11 (API 30) 開始,您可能需要在清單中聲明<queries> ,具體取決於您要查找的包。 查看文檔以獲取更多信息。

自 Android 11(API 級別 30)起,大多數用戶安裝的應用程序默認不可見。 在您的清單中,您必須靜態聲明您將獲取有關哪些應用程序的信息,如下所示:

<manifest>
    <queries>
        <!-- Explicit apps you know in advance about: -->
        <package android:name="com.example.this.app"/>
        <package android:name="com.example.this.other.app"/>
    </queries>
    
    ...
</manifest>

然后,@RobinKanters 的回答有效:

private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    try {
        packageManager.getPackageInfo(packageName, 0);
        return true;
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

// ...
// This will return true on Android 11 if the app is installed,
// since we declared it above in the manifest.
isPackageInstalled("com.example.this.app", pm); 
// This will return false on Android 11 even if the app is installed:
isPackageInstalled("another.random.app", pm); 

在此處了解更多信息:

Robin Kanters 的回答是正確的,但它會檢查已安裝的應用程序,無論它們處於啟用還是禁用狀態。

我們都知道應用程序可以安裝但被用戶禁用,因此無法使用。

這會檢查已安裝啟用的應用程序:

public static boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    try {
        return packageManager.getApplicationInfo(packageName, 0).enabled;
    }
    catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

您可以將此方法放在像Utils這樣的類中,並使用以下方法在任何地方調用它:

boolean isInstalled = Utils.isPackageInstalled("com.package.name", context.getPackageManager())

更快的解決方案:

private boolean isPackageInstalled(String packagename, PackageManager packageManager) {
    try {
        packageManager.getPackageGids(packagename);
        return true;
    } catch (NameNotFoundException e) {
        return false;
    }
}

getPackageGids是更便宜getPackageInfo ,所以它工作得更快。

Run 10000 on API 15
Exists pkg:
getPackageInfo: nanoTime = 930000000
getPackageGids: nanoTime = 350000000
Not exists pkg:
getPackageInfo: nanoTime = 420000000
getPackageGids: nanoTime = 380000000

Run 10000 on API 17
Exists pkg:
getPackageInfo: nanoTime = 2942745517
getPackageGids: nanoTime = 2443716170
Not exists pkg:
getPackageInfo: nanoTime = 2467565849
getPackageGids: nanoTime = 2479833890

Run 10000 on API 22
Exists pkg:
getPackageInfo: nanoTime = 4596551615
getPackageGids: nanoTime = 1864970154
Not exists pkg:
getPackageInfo: nanoTime = 3830033616
getPackageGids: nanoTime = 3789230769

Run 10000 on API 25
Exists pkg:
getPackageInfo: nanoTime = 3436647394
getPackageGids: nanoTime = 2876970397
Not exists pkg:
getPackageInfo: nanoTime = 3252946114
getPackageGids: nanoTime = 3117544269

注意:這在某些虛擬空間中不起作用。 它們可能違反 Android API 並始終返回一個數組,即使沒有具有該包名稱的應用程序。
在這種情況下,請使用getPackageInfo

試試這個:

public static boolean isAvailable(Context ctx, Intent intent) {
    final PackageManager mgr = ctx.getPackageManager();
    List<ResolveInfo> list =
        mgr.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

你可以在 Kotlin extentions.kt使用它

fun Context.isPackageInstalled(packageName: String): Boolean {
    return try {
        packageManager.getPackageInfo(packageName, 0)
        true
    } catch (e: PackageManager.NameNotFoundException) {
        false
    }
}

用法

context.isPackageInstalled("com.somepackage.name")

Android 11之后,您需要在 Manifest of Application 的<queries>中添加 package names。

如果清單中沒有<queries>context.getPackageManager().getApplicationInfo總是有異常( System.err: android.content.pm.PackageManager$NameNotFoundException

檢查參考:鏈接

例子:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <queries>
        <package android:name="com.xxx.yyy" />
    </queries>

    <application></application>

</manifest>

Java

 public boolean applicationIsInstall(Context context , String packageName){
        try {
            context.getPackageManager().getApplicationInfo(packageName, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }

科爾廷

fun applicationIsInstall(context: Context, packageName: String): Boolean {
    return try {
        context.packageManager.getApplicationInfo(packageName, 0)
        true
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
        false
    }
}

如果你想在沒有try catch塊的情況下嘗試,可以使用下面的方法,創建一個意圖並設置你要驗證的應用程序的包

val intent = Intent(Intent.ACTION_VIEW)
intent.data = uri
intent.setPackage("com.example.packageofapp")

並調用以下方法來檢查應用程序是否已安裝

fun isInstalled(intent:Intent) :Boolean{
    val list = context.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
    return list.isNotEmpty()
}

那些正在尋找 Kotlin 解決方案的人可以使用這種方法,

在這里我分享了完整的代碼,並且還處理了啟用狀態。 檢查 Android Kotlin 中是否安裝了應用程序

fun isAppInstalled(packageName: String, context: Context): Boolean {
        return try {
            val packageManager = context.packageManager
            packageManager.getPackageInfo(packageName, 0)
            true
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }
    }
    private boolean isAppExist() {

    PackageManager pm = getPackageManager();
    try {
        PackageInfo info = pm.getPackageInfo("com.facebook.katana", PackageManager.GET_META_DATA);
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
    return true;
}




if (isFacebookExist()) {showToast(" Facebook is  install.");}
     else {showToast(" Facebook is not install.");}
isFakeGPSInstalled = Utils.isPackageInstalled(Utils.PACKAGE_ID_FAKE_GPS, this.getPackageManager());

//檢查包安裝的方法真/假

  public static boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    boolean found = true;
    try {
      packageManager.getPackageInfo(packageName, 0);
    } catch (PackageManager.NameNotFoundException e) {
      found = false;
    }

    return found;
  }
@Override 
protected void onResume() {
    super.onResume();
    boolean installed = false;

    while (!installed) {
        installed = appInstalledOrNot (APPPACKAGE);
        if (installed) {
            Toast.makeText(this, "App installed", Toast.LENGTH_SHORT).show ();
        }
    }
} 

private boolean appInstalledOrNot (String uri) {
    PackageManager pm = getPackageManager();
    boolean app_installed = false;
    try {
        pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
        app_installed = true;
    } catch (PackageManager.NameNotFoundException e) {
        app_installed = false;
    }
    return app_installed;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM