Android : Launch Music Player via Service - android

I am trying to launch the MediaPlayer from a service, and its not wroking as expected. I m getting the following exception,
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.MUSIC_PLAYER flg=0x10000000 }
Please find the snippet of code that gets invoked in the service,
Intent intent = new Intent(MediaStore.INTENT_ACTION_MUSIC_PLAYER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Android Manifest
<service android:name="com.lakshmi.shakenfun.AlertService" >
<intent-filter >
<action android:name="android.intent.action.MUSIC_PLAYER" />
</intent-filter>
</service>
Please do let me know, where I am doing wrong.
My target platform is 8
Thanks,
Ramesh

Perhaps your Target Platform of 8 is too low for that api? Do you have this music player loaded? https://play.google.com/store/apps/details?id=com.google.android.music&feature=search_result#?t=W251bGwsMSwyLDEsImNvbS5nb29nbGUuYW5kcm9pZC5tdXNpYyJd

MediaStore.INTENT_ACTION_MUSIC_PLAYER is deprecated from API 15 the new code is:
try {
String pkgname = "com.sec.android.app.music";
PackageManager pkgmanager = getPackageManager();
Intent intent = pkgmanager.getLaunchIntentForPackage(pkgname);
startActivity(intent);
} catch(Exception e) {
// music player not found
}
Just add this code on your button listener and it will call the default music player.

Related

Binding to background services fails on Android OS 8

I need to start a few services provided by other apps, let them execute whatever the want to execute, and kill them once they call me back and I receive the data collected. Sadly startService(serviceIntent); crashes with
Unable to start activity ComponentInfo{…}: java.lang.IllegalStateException: Not allowed to start service Intent {…}: app is in background uid UidRecord{70fcf01 u0a90 CEM bg:+1h49m29s56ms idle procs:1 seq(0,0,0)}
It appears that this is by design, here's the crashing AOSP code.
My code crashing looks like this:
final PackageManager pm = getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory("my.special.service.CATEGORY");
List<ResolveInfo> results = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
for (ResolveInfo info : results) {
ComponentName name =
new ComponentName(info.serviceInfo.applicationInfo.packageName, info.serviceInfo.name);
Intent serviceIntent = new Intent();
serviceIntent.setComponent(name);
startService(serviceIntent); // 💥 K A B O O M
bindService(serviceIntent, boundServiceConnection, BIND_AUTO_CREATE);
}
The way service is defined in another app's Manifest.xml:
<service
android:name=".ServiceFromAnotherApp"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<categoy android:name="my.special.service.CATEGORY" />
</intent-filter>
</service>
Any ideas if there're any workarounds, maybe different architecture?
Core trait that I want to retain is:
to be able to create a service
tell it to fetch additional data (potentially several times during its lifecycle)
get callback from the service once it finishes every subsequence fetch

android explicit intent by name not resolving to other activity

I have 2 apps that are used in conjunction with one another. I want to create a button that launches app A from app B so I am creating an intent like so in app B:
Intent intent = new Intent("com.org.orgmobile.android.action.ACTION_CUSTOM");
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.setData(Uri.parse(url));
startActivity(intent);
where url is https://org.org.com/mobile/Support/action/org/ActionEnumValue/?a=123
the intent filter I have declared in app A's manifest is like so:
<intent-filter>
<action android:name="com.org.orgmobile.android.action.ACTION_CUSTOM"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="https"/>
<data android:host="org.org.com"/>
<data android:pathPrefix="/mobile/Support/action/${manifestplaceholderattr}.*/ActionEnumValue/*"/>
</intent-filter>
and manifestplaceholderattr is an empty string.
I am getting
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.org.orgmobile.android.action.ACTION_CUSTOM dat=https://org.org.com/... flg=0x20000000 }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1936)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1615)
at android.app.Activity.startActivityForResult(Activity.java:4472)
at android.app.Activity.startActivityForResult(Activity.java:4430)
at android.app.Activity.startActivity(Activity.java:4791)
at android.app.Activity.startActivity(Activity.java:4759)
What am I overlooking here? I have tried using pathPattern instead of path prefix with no success.
Edit: to provide more detail, I don't just want to launch that specific activity, I want to match the specific intent associated with that activity to launch the activity. I don't want to launch the activity directly because in the case that the user's app is out of date because it won't have the desired behavior.
Best way to do this through Package manager as below.
PackageManager manager = getPackageManager();
try {
Intent intent = manager.getLaunchIntentForPackage("app B package name here");
if (intent == null)
throw new PackageManager.NameNotFoundException();
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
Package manager checks if app with the given package name is installed, if exists it launches the app else it throws NameNotFoundException
You need to use pathPattern instead of pathPrefix. Also you should use .* instead of * at the end of the pattern:
<data android:pathPattern="/mobile/Support/action/${manifestplaceholderattr}.*/ActionEnumValue/.*"/>
This may also not work. If I recall, pathPattern isn't a real regular expression and you may not be able to match the URL like this. Try it and see. If this doesn't work, you'll probably need to rely on just the first part of the path. Let me know how it goes.
See the documentation on path, pathPattern and pathPrefix.
You need to use code as below to launch other App using custom action.
Intent intent = new Intent();
intent.setAction("com.org.orgmobile.android.action.ACTION_CUSTOM");
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.setData(Uri.parse(url));
startActivity(intent);
Also make sure both of your application is installed. Also it is better to have check as below to make sure application exists on the phone to handle such Intent.
PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;

ActivityNotFoundException: No Activity found to handle Intent

In fear of being that guy that asks the question that has been asked already.....*I have looked through the various solutions to this problem, and none seem to solve my problem.
I simply have a button that I would like to start a map activity.
Below is the activity:
public void OnclickButtonListener() {
button_map = (Button)findViewById(R.id.button);
button_map.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent mapintent = new Intent("mf.tutorial.MapsActivity");
startActivity(mapintent);
}
});
and the intent being handled in my manifest file:
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
The error returned looks like this:
ActivityNotFoundException: No Activity found to handle Intent { act=mf.tutorial.MapsActivity }
Any help is really appreciated as it has taken me ages to get this far and this is just the latest stumbling block. I would be happy to provide any other parts of the code that might be relevant for a solution!
Thank you very much!
I'm assuming MapsActivity is an activity in your apk? In that case, you would use Intent intent = new Intent(context, MapsActivity.class); The version of Intent you used is for running an activity that has an intent filter for a specific action. Usually used to access system apps like the camera app or the dialer.
When you try to launch your Activity, you do this:
Intent mapintent = new Intent("mf.tutorial.MapsActivity");
This creates an Intent and sets the ACTION in that Intent to "mf.tutorial.MapsActivity".
When you call startActivity(), Android tries to find an Activity in an installed application that knows how to deal with the ACTION "mf.tutorial.MapsActivity". There aren't any, so you get the ActivityNotFoundException.
What you are want to do is to launch the Activity by explicit COMPONENT, and NOT by implicit ACTION. Do that like this:
Intent mapintent = new Intent(context, MapsActivity.class);
startActivity(mapintent);
Using the 2-argument constructor allows you to set the COMPONENT (in this case, MapsActivity) explicitly. The parameter context should be a reference to the calling Activity.

How to disable/enable android receiver in source code?

I hava a question about Android Receiver.
I'm possible to change System app.
B is the first app, when user turns on the power. But the problem is when user chooses FACTORY Mode(like setting language, google id...), B App has to be started finishing A App setting. That's why use android:enabled="false"and A App trigger B app. But not working.
I think "android.intent.action.BOOT_COMPLETED" send just one time after booting, so after changing enable receiver B app, it's not working. Is it right?
Please can you give me some advise?
A App
PackageManager pm = getPackageManager();
ComponentName compName = new ComponentName("com.test.myapp", "com.test.myapp.receiver");
pm.setComponentEnabledSetting(compName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
B App AndoidManifest.xml
<receiver
android:name="com.test.myapp.receiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
B App
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())){
Intent startMainActivityIntent = new Intent(context, new.class);
startMainActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startMainActivityIntent);
}
Why don't you just start app B from app A directly? Yes, boot completed triggered only once. But you can start app B without any receivers, look here for example

How to start android service from another Android app

I'm having a problem starting a service from another Android app (API 17).
However, if I do run 'am' from the shell, the service starts fine.
# am startservice com.xxx.yyy/.SyncService
Starting service: Intent { act=android.intent.action.MAIN cat=
[android.intent.category.LAUNCHER] cmp=com.xxx.yyy/.SyncService }
(service starts fine at this point)
# am to-intent-uri com.xxx.yyy/.SyncService
intent:#Intent;action=android.intent.action.MAIN;
category=android.intent.category.LAUNCHER;
component=com.xxx.yyy/.SyncService;end
So, it doesn't look like I'm missing anything from the intent when I do the same in the code:
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.setComponent(new ComponentName("com.xxx.yyy", ".SyncService"));
ComponentName c = ctx.startService(i);
if (c == null) { Log.e(TAG, "failed to start with "+i); }
What I get is (the service is not running at that time):
E/tag( 4026): failed to start with Intent {
act=android.intent.action.MAIN
cat=[android.intent.category.LAUNCHER]
cmp=com.xxx.yyy/.SyncService }
I don't have an intent filter on the service, and I don't want to set one up, I'm really trying to understand what am I doing wrong starting it through its component name, or what may be making it impossible to do so.
You should be able to start your service like this:
Intent i = new Intent();
i.setComponent(new ComponentName("com.xxx.yyy", "com.xxx.yyy.SyncService"));
ComponentName c = ctx.startService(i);
You don't need to set ACTION or CATEGORY if you are specifying a specific component. Make sure that your service is properly defined in the manifest.
Start your service like this
Intent intent = new Intent();
intent.setComponent(new ComponentName("pkg", "cls"));
ComponentName c = getApplicationContext().startForegroundService(intent);
btw you actually need to use the applicationId, instead of the pkg. it can be found in the app gradle. I was struggling with that mistake for hours!
defaultConfig {
applicationId "com.xxx.zzz"
}
the cls is the name of your service declared in the manifest. example: com.xxx.yyy.yourService.
<service android:name="com.xxx.yyy.yourService"
android:exported="true"/>
As an addition to David Wasser's answer to make it work when targeting API 30 and above you also have to add either:
Required package name in queries tag in manifest:
<queries>
<package android:name="com.example.service.owner.app" />
</queries>
or permission
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
Additional info on package visibility changes here

Categories

Resources