Невозможно запустить новое намерение с помощью setClassName с другим пакетом в Android
Я хочу начать новое намерение динамически. Следовательно setClassName
кажется лучшим выбором.
Во-первых, я определяю 3 действия в Манифесте
<activity android:name="com.example.pkg2.Act" />
<activity android:name="com.example.pkg1.Act1" />
<activity android:name="com.example.pkg1.Act2" />
От com.example.pkg2.Act
:
Intent intent = new Intent();
if(index == 0) intent.setClassName(Act.this, "com.example.pkg1.Act1");
else intent.setClassName(Act.this, "com.example.pkg1.Act2");
startActivity(intent);
И получит это исключение:
Unable to find explicit activity class {com.example.pkg2.Act/com.example.pkg1.Act1}; have you declared this activity in your AndroidManifest.xml?
Похоже, мы можем использовать только setClassName
динамически запускать новую активность, но в том же пакете.
Есть идеи, чтобы решить эту проблему? Вся помощь приветствуется.
8 ответов
setClassName принимает контекст пакета в качестве первого параметра setClassName(Context packageContext, String className)
:
Intent intent = new Intent();
if(index == 0) {
intent.setClassName("com.example.pkg1", "com.example.pkg1.Act1");
} else {
intent.setClassName("com.example.pkg1", "com.example.pkg1.Act2");
startActivity(intent);
}
И в
<activity android:name="com.example.pkg2.Act" />
<activity android:name="com.example.pkg1.Act1" />
<activity android:name="com.example.pkg1.Act2" />
или вы попробуйте это:
if(index == 0) {
Intent intent = new Intent(Intent.ACTION_MAIN)
.addCategory(intent.CATEGORY_LAUNCHER)
.setClassName("com.example.pkg1", "com.example.pkg1.Act1")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_FROM_BACKGROUND)
.setComponent(new ComponentName("com.example.pkg1", "com.example.pkg1.Act1"));
getApplicationContext().startActivity(intent);
} else {
Intent intent = new Intent(Intent.ACTION_MAIN)
.addCategory(intent.CATEGORY_LAUNCHER)
.setClassName("com.example.pkg1", "com.example.pkg1.Act2")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_FROM_BACKGROUND)
.setComponent(new ComponentName("com.example.pkg1", "com.example.pkg1.Act2"));
getApplicationContext().startActivity(intent);
}
Первый параметр - это идентификатор приложения, расположенный в файле build.gradle.
Второй параметр - это полный путь к классу с его пакетом. например: intentObj.setClassName ("ApplicatioId", "com.youCompany.yourAppName.YourClassName")
Вы можете использовать следующий метод для создания намерения в контексте пакета:
Intent intent = new Intent(this, MyActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Таким образом, вы держите общий код.
НТН
Вы также можете запустить Действия таким образом. Попробуй это
Intent intent = new Intent();
Class<?> activityClass = Class.forName("your.application.package.name." + NameOfClassToOpen);
intent.setClass(this, activityClass);
И для того, чтобы использовать setClassName. Вы должны предоставить ему packageName и его путь к классу, как
intent.setClassName("your.application.package.name", "your.application.package.name.activityClass");
Используйте этот код, и все будет в порядке.
Intent intent = new Intent();
String resourcePackageName = getResources().getResourcePackageName(R.string.some_defined_resource);
intent.setClassName(getApplicationContext().getPackageName(),resourcePackageName + ".SubPackageName[/if any/].ClassName");
startActivity(intent);
intent.setClassName(packageName, className);
где
packageName - имя пакета, реализующего желаемый компонент, то есть пакет, к которому принадлежит вызывающая сторона.
className - полное имя класса [из другого пакета]
Звонить из com.example.pkg2.Act
:
intent.setClassName("com.example.pkg2", "com.example.pkg1.Act1");
Наиболее вероятная причина проблемы заключается в том, что данное имя класса не является классом, связанным с pkg2. Вот фрагмент кода, который я использовал для запуска намерения в приложении AndroidInstumentationTest.
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName("com.xxx.android.app",
"com.xxx.android.app.MainActivity")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mActivity = instrumentation.startActivitySync(intent);
Этот код отлично работает, запуская его из моего модуля приложения, в котором есть класс MainActivity. Это не сработает, если я попытаюсь использовать его в модуле, с которым не связан класс MainActivity. Судя по тому, что я прочитал о первоначальной постановке проблемы, похоже, что это то, что, по словам пользователя антикафе, пытался сделать. Я предполагаю, что внутри есть вызов "Class.forName(className, classLoader), где classLoader - это ClassLoader для данного пакета. И, конечно, это не удастся, поскольку этот пакет не связан.
И да, вам нужно добавить флаг "FLAG_ACTIVITY_NEW_TASK", как предлагали другие, по крайней мере, для ситуаций, когда у вас есть связанный класс!
Следуйте синтаксису, чтобы написать метод setClassName():
setClassName( pkgName, className )