In my application, i start another application (not activity) with this code :
protected void launchApp(String packageName) {
Intent mIntent = getPackageManager().getLaunchIntentForPackage(
packageName);
if (mIntent != null) {
try {
startActivity(mIntent);
} catch (ActivityNotFoundException err) {
Toast t = Toast.makeText(getApplicationContext(),
"App not found", Toast.LENGTH_SHORT);
t.show();
}
}
}
but i would like this application (launched by packageName) run in background and not disturb the UI.
Is it possible ?
Thanks!
you can use broadcast receiver in target app and start it with broadcast
Hope it will help
you can use this
startActivity(getPackageManager().getLaunchIntentForPackage("com.example.appName"));
further information please see this link
Android - How to start third party app with package name?
Related
I have two very simple apps. The first app should launch the second app. But I am running into problems.
The first app attempts to launch the second app like this:
val launchIntent = packageManager.getLaunchIntentForPackage("com.example.secondapp")
if (launchIntent != null) {
try {
startActivity(launchIntent)
Log.d("", "Launching com.example.secondapp")
} catch (e: ActivityNotFoundException) {
Log.d("", "Failed to launch com.example.secondapp")
}
} else {
Log.d("", "Intent is null value.")
}
The second app has first line
package com.example.secondapp
So the package name is correct. Yet the output of launching the first app is:
D/: Intent is null value.
So for some reason the second app is not being detected.
Any ideas why? Any ideas how to fix this?
Recently I have uploaded my android apk on the app store and its been told that the next upload to Google play store will get rejected and we need to check and resolve it. Below is the screenshot of the message:
They are referring to package name also. Below is the code:
#Override
public void onDestroy() {
cleanup();
super.onDestroy();
Intent intent = new Intent("com.test.dummyapp");
sendBroadcast(intent);
}
Please assist me how to resolve this.
Below is the code where the component is triggered:
IntentFilter restartFilter = new IntentFilter("com.test.dummyapp");
registerReceiver(restartBroadcastReciver, restartFilter);
private BroadcastReceiver restartBroadcastReciver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
doBindService();
}
};
When you do this, you are broadcasting an "implicit Intent". This is dangerous because any app can register to get this (potential leak of information) and any app can also broadcast this Intent (triggering your app).
Intent intent = new Intent("com.test.dummyapp");
sendBroadcast(intent);
To fix this you can use LocalBroadcastManager (it is deprecated, but still works). Using a local broadcast ensures that other apps cannot see your broadcast Intent and other apps cannot trigger your app this way.
See https://developer.android.com/reference/androidx/localbroadcastmanager/content/LocalBroadcastManager
As an alternative, you should be able to make the Intent explicit by setting the package name:
Intent intent = new Intent("com.test.dummyapp");
intent.setPackage("my.package.name");
sendBroadcast(intent);
It seems really weird to send a Broadcast in onDestroy. I can't possibly see a use for that, and I can see a lot of problems due to onDestroy being called unexpectedly (rotation, screen size change, etc).
But if you have to do it, use new Intent(getPackageName()). What they're looking for is a hardcoded package name like that. The problem is that if you run 'com.facebook.whateveritscalled' and a piece of malware is installed that named itself that, you would be sending the intent to it. Which if you have extras in the intent could be leaking information to it.
Thanks for the information.
I made some changes to the posted code. Let me know if this works fine.
#Override
public void onDestroy() {
cleanup();
super.onDestroy();
openApp((Context) context,"com.test.dummyapp");
}
public static boolean openApp(Context context, String packageName) {
PackageManager manager = context.getPackageManager();
try {
Intent i = manager.getLaunchIntentForPackage(packageName);
if (i == null) {
return false;
}
i.addCategory(Intent.CATEGORY_LAUNCHER);
context.sendBroadcast(i);
return true;
} catch (ActivityNotFoundException e) {
return false;
}
}
I can open skype activity but I dont know how to open my application after "skype calling" finish.
public static void skype(String number, Context ctx) {
try {
Intent sky = new Intent("android.intent.action.VIEW");
sky.setData(Uri.parse("skype:" + number));
ctx.startActivity(sky);
} catch (ActivityNotFoundException e) {
Log.e("SKYPE CALL", "Skype failed", e);
}
}
Close to skype after calling is enough for me first step. I searched phone broadcastrecevier but It doesnt detect anyting.
http://florent-dupont.blogspot.ro/2015/02/android-5-screen-pinning.html
From a pinned app, you cannot start a secondary app, unless this one
has the same shared user ID (which means that the sharedUserIdis set
in the AndroidManifest.xml and that second application is packaged
with the same certificate). Other apps’ Activities won’t be allowed to
be started and doing so (by using Context.startActivity()) will simply
be ignored.
I have done just those two things above but startActivity() is still getting ignored.
From https://developer.android.com/reference/android/R.attr.html#lockTaskMode:
If the system is already in lockTask mode when a new task rooted at
this activity is launched that task will or will not start depending
on whether the package of this activity has been whitelisted.
It looks tome like I have taken the necessary steps for this to work.
Anybody out there who got this working ?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
ComponentName deviceAdmin = new ComponentName(this, AdminReceiver.class);
mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
if (!mDpm.isAdminActive(deviceAdmin)) {
Toast.makeText(this, getString(R.string.not_device_admin), Toast.LENGTH_SHORT).show();
}
if (mDpm.isDeviceOwnerApp(getPackageName()))
{
mDpm.setLockTaskPackages(deviceAdmin, new String[]{getPackageName(), "com.that.other.package"});
try
{
enableKioskMode(true);
PackageManager pm = this.getPackageManager();
Intent it = pm.getLaunchIntentForPackage("com.that.other.package");
if (null != it) {
this.startActivity(it);
Log.d(_TAG, "Started activity for com.that.other.package");
}
}
catch (Exception e)
{
Log.e(_TAG, e.getMessage());
finish();
}
} else {
Toast.makeText(this, getString(R.string.not_device_owner), Toast.LENGTH_SHORT).show();
}
}
private void enableKioskMode(boolean enabled) throws Exception
{
if (enabled)
{
if (mDpm.isLockTaskPermitted(this.getPackageName()))
{
startLockTask();
mIsKioskEnabled = true;
mButton.setText(getString(R.string.exit_kiosk_mode));
} else {
Toast.makeText(this, getString(R.string.kiosk_not_permitted), Toast.LENGTH_SHORT).show();
}
} else {
stopLockTask();
mIsKioskEnabled = false;
mButton.setText(getString(R.string.enter_kiosk_mode));
}
}
Turned out I was missing the android:taskAffinity tag. Point it to the same strings in both packages and startActivity() should start behaving.
I have two applications, A and B, which use a android library C. B has a service A wants to use via C, e.g.
<service android:name="my.package.in.a.service.ConnectorService"
android:exported="true">
<intent-filter>
<action android:name="my.package.in.a.action.START_A"/>
</intent-filter>
</service>
In my library there is a class which tries to bind it to the service, e.g.
Intent intent = new Intent("my.package.in.a.service.ConnectorService");
/** establish a connection with the service. */
boolean result = context.bindService(intent, messenger,
Context.BIND_AUTO_CREATE);
Apparently, you can't do that anymore because of security issues (implicit vs. explicit intents). I've tried to initialise the intent using the action defined in A. I've also tried to add the package name and also tried to set the class name, e.g.
Intent intent = new Intent()
intent.setPackage("my.package.in.a.service");
intent.setClassName("my.package.in.a.service",
"my.package.in.a.service.ConnectorService");
I've als tried to find the service using the package manager, e.g.
Intent intent = new Intent("my.package.in.a.service.ConnectorService");
List<ResolveInfo> resolveInfoList = context.getPackageManager()
.queryIntentServices(intent, Context.BIND_AUTO_CREATE);
if (resolveInfoList.isEmpty()) {
Log.e(TAG, "could not find any service");
}
if (resolveInfoList.size() > 1) {
Log.e(TAG, "multiple services found");
}
I'm a bit puzzled what I'm doing wrong? As far as I understood it you can make an implicit intent explicit, even while it is not part of the same package/application, by simply specifying the package/classname. However, all this seems to fail and obviously I'm doing something wrong?
I don't think that setPackage() does "enough" to make it fully explicit. For that, you need setComponent().
Your second approach, using PackageManager, is on the right track, but unless you just truncated your code listing, you missed the adjust-the-Intent step.
In this sample app from this book, I not only check for a single implementation of the service, but I also check its signature (to ensure the app I want to bind to is not hacked) and adjust the Intent:
Intent implicit=new Intent(IDownload.class.getName());
List<ResolveInfo> matches=getActivity().getPackageManager()
.queryIntentServices(implicit, 0);
if (matches.size() == 0) {
Toast.makeText(getActivity(), "Cannot find a matching service!",
Toast.LENGTH_LONG).show();
}
else if (matches.size() > 1) {
Toast.makeText(getActivity(), "Found multiple matching services!",
Toast.LENGTH_LONG).show();
}
else {
ServiceInfo svcInfo=matches.get(0).serviceInfo;
try {
String otherHash=SignatureUtils.getSignatureHash(getActivity(),
svcInfo.applicationInfo.packageName);
String expected=getActivity().getString(R.string.expected_sig_hash);
if (expected.equals(otherHash)) {
Intent explicit=new Intent(implicit);
ComponentName cn=new ComponentName(svcInfo.applicationInfo.packageName,
svcInfo.name);
explicit.setComponent(cn);
appContext.bindService(explicit, this, Context.BIND_AUTO_CREATE);
}
else {
Toast.makeText(getActivity(), "Unexpected signature found!",
Toast.LENGTH_LONG).show();
}
}
catch (Exception e) {
Log.e(getClass().getSimpleName(), "Exception trying to get signature hash", e);
}
}