Android Source change to pass intent invoker to Broadcast Receiver - android

I am trying to modify the Android source so that a BroadcastReceiver can know who invoked the action.
android.app.activity:
#Override
public void startActivity(Intent intent) {
intent.putExtra("packageName", this.getPackageName());
startActivity(intent, null);
}
I wrote a testing app that has the CALL_PHONE permission. As a debugging step, I also tried to see if I could just pass something in the Intent from the calling app:
Calling App (App #1):
Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:8005551212"));
dialIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialIntent.putExtra("StubTest", "it worked!");
startActivity(dialIntent);
But in my BroadcastReceiver that intent does not have the intent value from the Activity source file change I made, nor the intent value I added from the invoking activity.
Separate App which has a Broadcast Receiver (App #2):
public class CallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Set<String> k = bundle.keySet();
if (k!=null && k.size() > 0) {
Iterator<String> i = k.iterator();
while (i.hasNext()) {
String key = i.next();
try {
System.out.println("KEY: " + key + "=" + bundle.getString(key));
} catch (Exception e) {
logIt("skipping KEY: " + key);
}
}
}
System.out.println(bundle.getString("packageName"));
System.out.println(bundle.getString("StubTest"));
However, "packageName" and "StubTest" are both null all the time.

Related

Is there a way to get or display the method name of an android app using another android app? [duplicate]

I want to launch an installed package from my Android application. I assume that it is possible using intents, but I didn't find a way of doing it. Is there a link, where to find the information?
If you don't know the main activity, then the package name can be used to launch the application.
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) {
startActivity(launchIntent);//null pointer check in case package name was not found
}
I know this has been answered but here is how I implemented something similar:
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);
}
Even better, here is the method:
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);
}
}
Removed duplicate code:
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);
}
I found the solution. In the manifest file of the application I found the package name: com.package.address and the name of the main activity which I want to launch: MainActivity
The following code starts this application:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
// 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;
}
Edit depending on comment
In some versions - as suggested in comments - the exception thrown may be different.
Thus the solution below is slightly modified
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);
}
Original Answer
Although answered well, there is a pretty simple implementation that handles if the app is not installed. I do it like this
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")));
}
Replace "applicationId" with the package that you want to open such as com.google.maps, etc.
Here is my example of launching bar/QR code scanner from my app if someone finds it useful
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();
}
If you want to open specific activity of another application we can use this.
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()
}
If you must need other application, instead of showing Toast you can show a dialog. Using dialog you can bring the user to Play-Store to download required application.
Check for the app, avoiding any crashes. If the app exists in the phone then it will be launched, otherwise it will search in Google Play. If no Google Play app installed in the phone, it will search in the Google Play Store via 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);
}
}
Starting from API 30 (Android 11) you can receive nullpointerexception with launchIntentForPackage
val launchIntent: Intent? = activity.packageManager.getLaunchIntentForPackage("com.google.android.gm")
startActivity(launchIntent)
To avoid this you need to add the needed package to the manifest
<queries>
<package android:name="com.google.android.gm" />
</queries>
Here is documentation
https://developer.android.com/training/package-visibility
And the medium article
https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9
It is possible to start an app's activity by using Intent.setClassName according to the docs.
An example:
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)
To open it outside the current app, add this flag before starting the intent.
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
A related answer here
If you know the data and the action the installed package react on, you simply should add these information to your intent instance before starting it.
If you have access to the AndroidManifest of the other app, you can see all needed information there.
Steps to launch new activity as follows:
1.Get intent for package
2.If intent is null redirect user to playstore
3.If intent is not null open activity
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);
}
}
private fun openOtherApp() {
val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
startActivity(sendIntent)
finishAffinity()
}
This will cover all scenarios
1.Get intent for package
2.If intent is null redirect user to playstore
3.If there is an issue with open playstore, then it opens on the default browser.
var intent = activity!!.packageManager.getLaunchIntentForPackage("com.google.android.youtube")
if (intent == null) {
if (intent == null) {
intent = try {
Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.youtube"))
} catch (e: Exception) {
Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.google.android.youtube"))
}
}
startActivity(intent)
For Android 11 (API level 30) or higher, in AndroidManifest.xml,
<queries>
<package android:name="com.google.android.youtube" />
<package android:name="com.example.app" />
</queries>
Or simply we can allow for all packages (not recommended)
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
References
Package visibility filtering on Android
Declaring package visibility needs
Try code below:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("package_name", "Class_name"));
if (intent.resolveActivity(getPackageManager()) != null)
{
startActivity(intent);
}
In Kotlin
fun openApplicationOrMarket(packageName: String) {
var intent = requireContext().packageManager.getLaunchIntentForPackage(packageName)
if (intent == null) {
intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("market://details?id=$packageName")
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(intent)
}
Pass the package name and the message you want to show if package isn't installed ;-)
void openApp(String appPackageName,String message){
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(appPackageName);
if (launchIntent != null) {
startActivity(launchIntent);
} else {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
}
Since kotlin is becoming very popular these days, I think it's appropriate to provide a simple solution in Kotlin as well.
var launchIntent: Intent? = null
try {
launchIntent = packageManager.getLaunchIntentForPackage("applicationId")
} catch (ignored: Exception) {
}
if (launchIntent == null) {
startActivity(Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")))
} else {
startActivity(launchIntent)
}

Android - share (java code) number

How I share (java code) from my android application a phone number, so that it can mark it or send it by email at a time.
Thank you very much
Here's my code:
#Override
public void onClick(View view) {
TextView txtphone = (TextView) findViewById(R.id.txtphone1);
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + txtphone.getText()));
try {
startActivity(intent);
}catch (Throwable e) {
message("ERROR: startActivity - " + e.toString());
return;
}
return;
}
try this
public static void shareText(#NonNull Activity activity, #NonNull String text) {
Intent shareIntent = ShareCompat.IntentBuilder.from(activity)
.setType("text/plain")
.setText(text)
.getIntent();
if (shareIntent.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivity(shareIntent);
}
}
here's a great article about sharing - https://medium.com/google-developers/sharing-content-between-android-apps-2e6db9d1368b#.ommhqdbhy

Android open another app and jump to specific Activity [duplicate]

I want to launch an installed package from my Android application. I assume that it is possible using intents, but I didn't find a way of doing it. Is there a link, where to find the information?
If you don't know the main activity, then the package name can be used to launch the application.
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) {
startActivity(launchIntent);//null pointer check in case package name was not found
}
I know this has been answered but here is how I implemented something similar:
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);
}
Even better, here is the method:
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);
}
}
Removed duplicate code:
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);
}
I found the solution. In the manifest file of the application I found the package name: com.package.address and the name of the main activity which I want to launch: MainActivity
The following code starts this application:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
// 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;
}
Edit depending on comment
In some versions - as suggested in comments - the exception thrown may be different.
Thus the solution below is slightly modified
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);
}
Original Answer
Although answered well, there is a pretty simple implementation that handles if the app is not installed. I do it like this
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")));
}
Replace "applicationId" with the package that you want to open such as com.google.maps, etc.
Here is my example of launching bar/QR code scanner from my app if someone finds it useful
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();
}
If you want to open specific activity of another application we can use this.
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()
}
If you must need other application, instead of showing Toast you can show a dialog. Using dialog you can bring the user to Play-Store to download required application.
Check for the app, avoiding any crashes. If the app exists in the phone then it will be launched, otherwise it will search in Google Play. If no Google Play app installed in the phone, it will search in the Google Play Store via 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);
}
}
Starting from API 30 (Android 11) you can receive nullpointerexception with launchIntentForPackage
val launchIntent: Intent? = activity.packageManager.getLaunchIntentForPackage("com.google.android.gm")
startActivity(launchIntent)
To avoid this you need to add the needed package to the manifest
<queries>
<package android:name="com.google.android.gm" />
</queries>
Here is documentation
https://developer.android.com/training/package-visibility
And the medium article
https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9
It is possible to start an app's activity by using Intent.setClassName according to the docs.
An example:
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)
To open it outside the current app, add this flag before starting the intent.
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
A related answer here
If you know the data and the action the installed package react on, you simply should add these information to your intent instance before starting it.
If you have access to the AndroidManifest of the other app, you can see all needed information there.
Steps to launch new activity as follows:
1.Get intent for package
2.If intent is null redirect user to playstore
3.If intent is not null open activity
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);
}
}
private fun openOtherApp() {
val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
startActivity(sendIntent)
finishAffinity()
}
This will cover all scenarios
1.Get intent for package
2.If intent is null redirect user to playstore
3.If there is an issue with open playstore, then it opens on the default browser.
var intent = activity!!.packageManager.getLaunchIntentForPackage("com.google.android.youtube")
if (intent == null) {
if (intent == null) {
intent = try {
Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.youtube"))
} catch (e: Exception) {
Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.google.android.youtube"))
}
}
startActivity(intent)
For Android 11 (API level 30) or higher, in AndroidManifest.xml,
<queries>
<package android:name="com.google.android.youtube" />
<package android:name="com.example.app" />
</queries>
Or simply we can allow for all packages (not recommended)
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
References
Package visibility filtering on Android
Declaring package visibility needs
Try code below:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("package_name", "Class_name"));
if (intent.resolveActivity(getPackageManager()) != null)
{
startActivity(intent);
}
In Kotlin
fun openApplicationOrMarket(packageName: String) {
var intent = requireContext().packageManager.getLaunchIntentForPackage(packageName)
if (intent == null) {
intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("market://details?id=$packageName")
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(intent)
}
Pass the package name and the message you want to show if package isn't installed ;-)
void openApp(String appPackageName,String message){
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(appPackageName);
if (launchIntent != null) {
startActivity(launchIntent);
} else {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
}
Since kotlin is becoming very popular these days, I think it's appropriate to provide a simple solution in Kotlin as well.
var launchIntent: Intent? = null
try {
launchIntent = packageManager.getLaunchIntentForPackage("applicationId")
} catch (ignored: Exception) {
}
if (launchIntent == null) {
startActivity(Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")))
} else {
startActivity(launchIntent)
}

How do I open an Android intent in a specific application? [duplicate]

I want to launch an installed package from my Android application. I assume that it is possible using intents, but I didn't find a way of doing it. Is there a link, where to find the information?
If you don't know the main activity, then the package name can be used to launch the application.
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) {
startActivity(launchIntent);//null pointer check in case package name was not found
}
I know this has been answered but here is how I implemented something similar:
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);
}
Even better, here is the method:
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);
}
}
Removed duplicate code:
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);
}
I found the solution. In the manifest file of the application I found the package name: com.package.address and the name of the main activity which I want to launch: MainActivity
The following code starts this application:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
// 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;
}
Edit depending on comment
In some versions - as suggested in comments - the exception thrown may be different.
Thus the solution below is slightly modified
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);
}
Original Answer
Although answered well, there is a pretty simple implementation that handles if the app is not installed. I do it like this
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")));
}
Replace "applicationId" with the package that you want to open such as com.google.maps, etc.
Here is my example of launching bar/QR code scanner from my app if someone finds it useful
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();
}
If you want to open specific activity of another application we can use this.
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()
}
If you must need other application, instead of showing Toast you can show a dialog. Using dialog you can bring the user to Play-Store to download required application.
Check for the app, avoiding any crashes. If the app exists in the phone then it will be launched, otherwise it will search in Google Play. If no Google Play app installed in the phone, it will search in the Google Play Store via 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);
}
}
Starting from API 30 (Android 11) you can receive nullpointerexception with launchIntentForPackage
val launchIntent: Intent? = activity.packageManager.getLaunchIntentForPackage("com.google.android.gm")
startActivity(launchIntent)
To avoid this you need to add the needed package to the manifest
<queries>
<package android:name="com.google.android.gm" />
</queries>
Here is documentation
https://developer.android.com/training/package-visibility
And the medium article
https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9
It is possible to start an app's activity by using Intent.setClassName according to the docs.
An example:
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)
To open it outside the current app, add this flag before starting the intent.
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
A related answer here
If you know the data and the action the installed package react on, you simply should add these information to your intent instance before starting it.
If you have access to the AndroidManifest of the other app, you can see all needed information there.
Steps to launch new activity as follows:
1.Get intent for package
2.If intent is null redirect user to playstore
3.If intent is not null open activity
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);
}
}
private fun openOtherApp() {
val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
startActivity(sendIntent)
finishAffinity()
}
This will cover all scenarios
1.Get intent for package
2.If intent is null redirect user to playstore
3.If there is an issue with open playstore, then it opens on the default browser.
var intent = activity!!.packageManager.getLaunchIntentForPackage("com.google.android.youtube")
if (intent == null) {
if (intent == null) {
intent = try {
Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.youtube"))
} catch (e: Exception) {
Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.google.android.youtube"))
}
}
startActivity(intent)
For Android 11 (API level 30) or higher, in AndroidManifest.xml,
<queries>
<package android:name="com.google.android.youtube" />
<package android:name="com.example.app" />
</queries>
Or simply we can allow for all packages (not recommended)
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
References
Package visibility filtering on Android
Declaring package visibility needs
Try code below:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("package_name", "Class_name"));
if (intent.resolveActivity(getPackageManager()) != null)
{
startActivity(intent);
}
In Kotlin
fun openApplicationOrMarket(packageName: String) {
var intent = requireContext().packageManager.getLaunchIntentForPackage(packageName)
if (intent == null) {
intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("market://details?id=$packageName")
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(intent)
}
Pass the package name and the message you want to show if package isn't installed ;-)
void openApp(String appPackageName,String message){
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(appPackageName);
if (launchIntent != null) {
startActivity(launchIntent);
} else {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
}
Since kotlin is becoming very popular these days, I think it's appropriate to provide a simple solution in Kotlin as well.
var launchIntent: Intent? = null
try {
launchIntent = packageManager.getLaunchIntentForPackage("applicationId")
} catch (ignored: Exception) {
}
if (launchIntent == null) {
startActivity(Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")))
} else {
startActivity(launchIntent)
}

Query supported languages for SpeechRecognizer using BroadcastReceiver intent

I'm having trouble querying for supported languages using the SpeechRecognizer.ACTION_GET_SUPPORTED_LANGUAGES.
private void queryLanguages() {
Intent i = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
sendOrderedBroadcast(i, null);
}
Now, I know it says the BroadcastReceiver is specified in RecognizerIntent.DETAILS_META_DATA, but I'm not sure as to how I can access that.
So basically what I'm asking is how do I create an Intent to retrieve the available languages data?
This is how it is done:
Intent intent = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
context.sendOrderedBroadcast(intent, null, new HintReceiver(),
null, Activity.RESULT_OK, null, null);
private static class HintReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (DBG)
Log.d(TAG, "onReceive(" + intent.toUri(0) + ")");
if (getResultCode() != Activity.RESULT_OK) {
return;
}
// the list of supported languages.
ArrayList<CharSequence> hints = getResultExtras(true)
.getCharSequenceArrayList(
RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);
}
}
Note :
Whether these are actually provided is up to the particular implementation

Categories

Resources