По вопросу «что мне делать с этим» может быть много ответов.
Более «формальный» способ предотвращения таких ошибок при разработке применяя дизайн по контракту в вашем коде. Это означает, что при разработке вы должны установить инварианты класса и / или даже предпосылки для функции и . Короче говоря, инварианты класса гарантируют, что в вашем классе будут некоторые ограничения, которые не будут нарушены при нормальном использовании (и, следовательно, класс будет not получить в несогласованном состоянии). Предпосылки означают, что данные, данные как входные данные для функции / метода, должны соответствовать установленным ограничениям и никогда не нарушать их, а постулаты означают, что вывод функции / метода должен соответствовать установленным ограничениям снова не нарушая их. Условия контракта никогда не должны нарушаться во время выполнения программы без ошибок, поэтому дизайн по контракту проверяется на практике в режиме отладки, а отключен в выпусках , чтобы максимизировать развитую производительность системы. Таким образом, вы можете избежать случаев Но если вы установите «свойство X никогда не должно иметь нулевого значения» в качестве предпосылки для метода, вы можете предотвратить описанный ранее сценарий: По этой причине Код Контракт существует для приложений .NET. В качестве альтернативы дизайн по контракту может быть применен с использованием утверждений . ОБНОВЛЕНИЕ: Стоит отметить, что этот термин был придуман Бертраном Майером в связи с его дизайном языка программирования Эйфеля . NullReferenceException
, которые являются результатом нарушения установленных ограничений. Например, если вы используете свойство объекта X
в классе, а затем попытаетесь вызвать один из его методов, а X
имеет нулевое значение, то это приведет к NullReferenceException
: public X { get; set; }
public void InvokeX()
{
X.DoSomething(); // if X value is null, you will get a NullReferenceException
}
//Using code contracts:
[ContractInvariantMethod]
protected void ObjectInvariant ()
{
Contract.Invariant ( X != null );
//...
}
Во-первых, понятие «приложение» в Android немного расширено.
Приложение - технически процесс - может иметь несколько действий, сервисов, поставщиков контента и / или широковещательных слушателей. Если хотя бы один из них запущен, приложение работает и работает (процесс).
Итак, вам нужно определить, как вы хотите «запустить приложение».
Хорошо ... вот что вы можете попробовать:
action=MAIN
и category=LAUNCHER
PackageManager
от текущего контекст с использованием context.getPackageManager
packageManager.queryIntentActivity(<intent>, 0)
, где у цели есть category=LAUNCHER
, action=MAIN
или packageManager.resolveActivity(<intent>, 0)
, чтобы получить первое действие с помощью main / launcher ActivityInfo
вы интересуетесь ActivityInfo
получите packageName
и name
category=LAUNCHER
, action=MAIN
, componentName = new ComponentName(packageName, name)
и setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(newIntent)
Я работаю так:
/** Open another app.
* @param context current Context, like Activity, App, or Service
* @param packageName the full package name of the app to open
* @return true if likely successful, false if unsuccessful
*/
public static boolean openApp(Context context, String packageName) {
PackageManager manager = context.getPackageManager();
try {
Intent i = manager.getLaunchIntentForPackage(packageName);
if (i == null) {
return false;
//throw new ActivityNotFoundException();
}
i.addCategory(Intent.CATEGORY_LAUNCHER);
context.startActivity(i);
return true;
} catch (ActivityNotFoundException e) {
return false;
}
}
Пример использования:
openApp(this, "com.google.android.maps.mytracks");
Надеюсь, что это кому-то поможет.
getLaunchIntentForPackage
.
– Chris Lacy
28 April 2013 в 12:12
getLaunchIntentForPackage()
уже добавляет категорию, см. источник: github.com/android/platform_frameworks_base/blob/master/core/…
– jrub
6 March 2015 в 12:40
Попробуйте этот код, надеюсь, это вам поможет. Если этот пакет доступен, это откроет приложение или откроет магазин воспроизведения для загрузки
String packageN = "aman4india.com.pincodedirectory";
Intent i = getPackageManager().getLaunchIntentForPackage(packageN);
if (i != null) {
i.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(i);
} else {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageN)));
}
catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + packageN)));
}
}
Intent launchIntent = getActivity.getPackageManager().getLaunchIntentForPackage("com.ionicframework.uengage");
startActivity(launchIntent);
Если вы пытаетесь запустить SERVICE, а не активность, это сработало для меня:
Intent intent = new Intent();
intent.setClassName("com.example.otherapplication", "com.example.otherapplication.ServiceName");
context.startService(intent);
Если вы используете метод intent.setComponent (...), как упоминается в других ответах, вы можете получить предупреждение «Неявные намерения с startService не безопасны».
В качестве альтернативы вы также можете открыть намерение своего приложения в другом приложении:
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
, где uri
является отключением другого приложения
Откройте приложение, если оно существует, или откройте приложение Play Store для его установки:
private void open() {
openApplication(getActivity(), "com.app.package.here");
}
public void openApplication(Context context, String packageN) {
Intent i = context.getPackageManager().getLaunchIntentForPackage(packageN);
if (i == null) {
i.addCategory(Intent.CATEGORY_LAUNCHER);
context.startActivity(i);
} else {
try {
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageN)));
}
catch (android.content.ActivityNotFoundException anfe) {
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + packageN)));
}
}
}
// Это работает на Android Lollipop 5.0.2
public static boolean launchApp(Context context, String packageName) {
final PackageManager manager = context.getPackageManager();
final Intent appLauncherIntent = new Intent(Intent.ACTION_MAIN);
appLauncherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfos = manager.queryIntentActivities(appLauncherIntent, 0);
if ((null != resolveInfos) && (!resolveInfos.isEmpty())) {
for (ResolveInfo rInfo : resolveInfos) {
String className = rInfo.activityInfo.name.trim();
String targetPackageName = rInfo.activityInfo.packageName.trim();
Log.d("AppsLauncher", "Class Name = " + className + " Target Package Name = " + targetPackageName + " Package Name = " + packageName);
if (packageName.trim().equals(targetPackageName)) {
Intent intent = new Intent();
intent.setClassName(targetPackageName, className);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
Log.d("AppsLauncher", "Launching Package '" + packageName + "' with Activity '" + className + "'");
return true;
}
}
}
return false;
}
Это код моей базы решений на решении MasterGaurav:
private void launchComponent(String packageName, String name){
Intent launch_intent = new Intent("android.intent.action.MAIN");
launch_intent.addCategory("android.intent.category.LAUNCHER");
launch_intent.setComponent(new ComponentName(packageName, name));
launch_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(launch_intent);
}
public void startApplication(String application_name){
try{
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
List<ResolveInfo> resolveinfo_list = activity.getPackageManager().queryIntentActivities(intent, 0);
for(ResolveInfo info:resolveinfo_list){
if(info.activityInfo.packageName.equalsIgnoreCase(application_name)){
launchComponent(info.activityInfo.packageName, info.activityInfo.name);
break;
}
}
}
catch (ActivityNotFoundException e) {
Toast.makeText(activity.getApplicationContext(), "There was a problem loading the application: "+application_name,Toast.LENGTH_SHORT).show();
}
}
Вы можете использовать эту команду для поиска имен пакетов, установленных на устройстве:
adb shell pm list packages -3 -f
Ссылка: http://www.aftvnews.com/how-to-determine-the -package-имя-ан-андроид-приложение /
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(ComponentName.unflattenFromString("com.google.android.maps.mytracks/com.google.android.apps.mytracks.MyTracks"));
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
EDIT:
, как предложено в комментариях, добавить одну строку до startActivity(intent);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Запустить другую активность приложения из моего приложения. Это работает для меня.
Ниже код будет работать, если другое приложение уже установлено в вашем телефоне, иначе невозможно перенаправить одно приложение в другое приложение. Убедитесь, что ваше приложение запущено или нет
Intent intent = new Intent();
intent.setClassName("com.xyz.myapplication", "com.xyz.myapplication.SplashScreenActivity");
startActivity(intent);
Если у вас уже есть имя пакета, которое вы хотите активировать, вы можете использовать следующий код, который является более общим:
PackageManager pm = context.getPackageManager();
Intent appStartIntent = pm.getLaunchIntentForPackage(appPackageName);
if (null != appStartIntent)
{
context.startActivity(appStartIntent);
}
Я обнаружил, что он работает лучше для случаев, когда основное действие не был найден обычным методом запуска MAIN-активности.
Используя решение от inversus, я расширил фрагмент с помощью функции, которая будет вызываться, когда требуемое приложение не будет установлено в данный момент. Так оно работает как: Запустить приложение по имени пакета. Если не найден, откройте Android-рынок - Google будет играть за этот пакет .
public void startApplication(String packageName)
{
try
{
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
List<ResolveInfo> resolveInfoList = getPackageManager().queryIntentActivities(intent, 0);
for(ResolveInfo info : resolveInfoList)
if(info.activityInfo.packageName.equalsIgnoreCase(packageName))
{
launchComponent(info.activityInfo.packageName, info.activityInfo.name);
return;
}
// No match, so application is not installed
showInMarket(packageName);
}
catch (Exception e)
{
showInMarket(packageName);
}
}
private void launchComponent(String packageName, String name)
{
Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
intent.setComponent(new ComponentName(packageName, name));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private void showInMarket(String packageName)
{
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageName));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
И он используется следующим образом:
startApplication("org.teepee.bazant");
Для уровня API 3+ не более одной строки кода:
Intent intent = context.getPackageManager().getLaunchIntentForPackage("name.of.package");
Возвращает запуск CATEGORY_INFO Intent (приложения без активности запуска, обои, например, часто используйте это, чтобы предоставить некоторую информацию о приложении), и, если его не найти, возвращает CATEGORY_LAUNCH пакета, если он существует.
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("package_name","package_name.class_name"));
intent.putExtra("grace", "Hi");
startActivity(intent);
Используйте это:
PackageManager pm = getPackageManager();
Intent intent = pm.getLaunchIntentForPackage("com.package.name");
startActivity(intent);
Поскольку приложениям не разрешено изменять многие из настроек телефона, вы можете открыть активность настроек точно так же, как и в другом приложении.
Посмотрите на результат LogCat после того, как вы действительно изменили настройку вручную:
INFO/ActivityManager(1306): Starting activity: Intent { act=android.intent.action.MAIN cmp=com.android.settings/.DevelopmentSettings } from pid 1924
Затем используйте это, чтобы отобразить страницу настроек из вашего приложения:
String SettingsPage = "com.android.settings/.DevelopmentSettings";
try
{
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(ComponentName.unflattenFromString(SettingsPage));
intent.addCategory(Intent.CATEGORY_LAUNCHER );
startActivity(intent);
}
catch (ActivityNotFoundException e)
{
log it
}
Использовать следующее:
String packagename = "com.example.app";
startActivity(getPackageManager().getLaunchIntentForPackage(packagename));
Если вы хотите открыть другое приложение и оно не установлено, вы можете отправить его в Магазин приложений Google для загрузки
public static boolean openApp(Context context, String packageName) {
PackageManager manager = context.getPackageManager();
try {
Intent intent = manager.getLaunchIntentForPackage(packageName);
if (intent == null) {
//the app is not installed
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 (ActivityNotFoundException e) {
//throw new ActivityNotFoundException();
return false;
}
}
intent.addCategory(Intent.CATEGORY_LAUNCHER);
context.startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
return false;
}
}
2.- Использование
openOtherApp(getApplicationContext(), "com.packageappname");
onCreate
= & gt;Bundle extras = getIntent().getExtras()
= & gt;if(extras != null) { extras.getString("blah") }
и т. д. – Gaurav Vaish 19 November 2013 в 03:24getPackageManager().getLaunchIntentForPackage()
уже делает все это для вас github.com/android/platform_frameworks_base/blob/master/core/… – jrub 6 March 2015 в 12:38