can anyone give me help:
I have put this code is work well if my app is last app opened. but if I open other app after my app, she's stays in background.
if anyone can give me how I can run my application as if it's the last open application or something else like its.
code:
public void Show_App(String packageName){
this.activity.getWindow().addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED|
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
Intent startIntent =
context.getPackageManager().getLaunchIntentForPackage(packageName);
startIntent.setFlags(
Intent.FLAG_ACTIVITY_REORDER_TO_FRONT |
Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
);
this.context.startActivity(startIntent);
}
private void getRecentAppList() {
ActivityManager mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RecentTaskInfo> recentTasks = mActivityManager.getRecentTasks(10, 0);
for (ActivityManager.RecentTaskInfo taskInfo : recentTasks) {
String packagename = task.baseIntent.getComponent().getPackageName();
Intent intent = taskInfo.baseIntent;
ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0);
ActivityInfo activityInfo = resolveInfo.activityInfo;
} }
you didn't close or clear app in recent list than recent app lunch list is get.
Related
If you have an accessibility service that detects events like this:
#Override
public void onAccessibilityEvent(AccessibilityEvent event) { //Called whenever the accessibility service gets an accessibility event
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (event.getPackageName() != null && event.getClassName() != null) {
//Component can be an activity, service, BroadcastReceiver, ContentProvider
ComponentName componentName = new ComponentName( //Component can be an activity, service, BroadcastReceiver, ContentProvider
event.getPackageName().toString(),
event.getClassName().toString()
);
ActivityInfo activityInfo = getPackageManager().getActivityInfo(componentName, 0);
boolean isActivity = activityInfo != null;
if (isActivity) {
Log.i(TAG, "packageName for this activity is " + event.getPackageName().toString());
}
}
}
}
I don't actually know what the package name for the launcher is on many devices. Does it have a package name or something else that can be detected in an accessibility service?
You should be able to find what packages are launchers by looking for the "home" activity:
PackageManger pm = getPackageManager();
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> launchers = pm.queryIntentActivities(homeIntent, PackageManager.MATCH_ALL);
String packages[] = new String[launchers.size()];
for (int i = 0; i < launchers.size(); i++) {
packages[i] = laycnhers.get(i).activityInfo.packageName;
}
Do this when you accessibility service initializes, than check if the package for the accessibility event is in the array.
Normally, there should be only one such package, but if the user installed 3rd party launcher or the OEM included optional launcher there may be more.
I have an Unity app, that has Android plugin that can launch other applications that installed on my smartphone. Here My Java class:
public class LaunchOtherApp extends Activity
{
public static Activity mainActivity;
protected static final String LOGTAG = "MyApp";
private Activity currentActivity;
private Intent i;
private static final LaunchOtherApp ourInstance = new LaunchOtherApp();
public static LaunchOtherApp getInstance() {
return ourInstance;
}
public LaunchOtherApp(){
Log.i(LOGTAG,"Created LaunchOtherApp");
}
public void Launch( final String pack)
{
mainActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
Intent intent = new Intent();
intent.setPackage(pack);
currentActivity = UnityPlayer.currentActivity;
Context context = currentActivity.getApplicationContext();
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
Collections.sort(resolveInfos, new ResolveInfo.DisplayNameComparator(pm));
if (resolveInfos.size() > 0)
{
try
{
ResolveInfo launchable = resolveInfos.get(0);
ActivityInfo activity = launchable.activityInfo;
ComponentName name = new ComponentName(activity.applicationInfo.packageName, activity.name);
i = new Intent(Intent.ACTION_MAIN);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
i.setComponent(name);
context.startActivity(i);
}
catch (SecurityException e)
{
intent = getPackageManager().getLaunchIntentForPackage(pack);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
}
}
}
});
}
#Override
public void onBackPressed() {
finish();
}
Launch - it is method that starting when I click on button in my Unity app... pack variable - it is variable that my Java method receive, and in this variable instantiate Application id. For Example I launched Youtube from my app, and when I pressing Back on my phone, I want to close Youtube, and back to my Unity app... I think I must use onBackPressed method that start when I press Back, but what I must write in this method?
finish(); doesn't help me(( Please, help... Thank you in advance!
Actually, YouTube app is a separate app (might be installed) and you cannot modify that app's behavior. On your button press, Launch method is called and assume YouTube app has started. With the intent:
If you use Intent.FLAG_ACTIVITY_NEW_TASK
YouTube app will start in a new task than yours and pressing back will not return to your app.
If you do not use Intent.FLAG_ACTIVITY_NEW_TASK
The new intent (here YouTube) will be launched in the task of calling activity (your app/game) by default and calling activity will go background. So, pressing back will again return to your app/game as you desired. Because back button press always pops from the backstack of the current task.
So, in the try block of your Launch method, removing the following line should help.
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
For more information about task and back stack, here is the official doc.
Edit
I missed that you have used application context. But, you have to launch from your calling activity context, otherwise you must use this flag. So, I have modified your Launch method and put it here, just replace your Launch method with following:
/* Method to launch an app with its package name */
public void Launch( final String pack)
{
mainActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
// Using activity context instead of application context
currentActivity = UnityPlayer.currentActivity;
Context context = currentActivity;
PackageManager pm = context.getPackageManager();
// Similar code to launch from package name
Intent intent = pm.getLaunchIntentForPackage(pack);
if (intent == null) {
// The activity cannot be found or the package name cannot be recognized
// Show some message or do something
Toast.makeText(context, "Cannot launch...", Toast.LENGTH_SHORT).show();
} else {
context.startActivity(intent);
}
}
});
}
I am working on a device running Android 8.1.0. I'm trying to open an image from a message attachment. I had a cache of image files working using a FileProvider a week ago and now it just stopped working without me touching the code. I'm trying to share an image from my internal app storage to Intent.ACTION_VIEW outside of my app. The photo viewer does launch, but there's a progress circle that just keeps spinning. Any suggestions? Thanks!
void launchViewer(File f) {
Uri uri = FileProvider.getUriForFile(context, "com.company.secure.provider", f);
Intent intent = new Intent(Intent.ACTION_VIEW);
String mimeType = Attachment.getMimeType(f.getName());
//TODO Test to make sure this works on all devices...
if (mimeType.startsWith("video")) {
mimeType = "video/*";
}
if (mimeType.startsWith("image")) {
mimeType = "image/*";
}
if(mimeType==null || mimeType.length()==0) {
unknownMimeType(f.getName());
return;
}
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if(resInfoList==null || resInfoList.size()==0)
{
AlertDialog dialog = new AlertDialog.Builder(context).setTitle("Error")
.setMessage(String.format("Cannot find app to open file type(%s)",mimeType)).show();
return;
}
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.setDataAndType(uri, mimeType);
context.startActivity(intent);
}
So I just had to add the following line right before starting the activity.
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
For some reason, the APK I shipped to testing that doesn't have this line in it works... but any new build does not work without this. I read that using the ResolveInfo method will only work for Lollipop and below and you will have to grant the permission directly to the intent. (Not sure how true this is). For this reason I left both permission granting methods in there to cover all bases. Thanks for all the help!
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Inside my app, I want to detect if an app like VLC is installed.
If it does, and when user clicks button, my app will proceed to play a video but if does not, the app will direct user to App store to download the app.
Is there a way to detect if an particular app is installed or not?
Try this:
PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(***REPLACE_WITH_YOUR_INTENT***,
PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;
From the Android Docs:
Although the Android platform guarantees that certain intents will
resolve to one of the built-in apps (such as the Phone, Email, or
Calendar app), you should always include a verification step before
invoking an intent.
To verify there is an activity available that can respond to the
intent, call queryIntentActivities() to get a list of activities
capable of handling your Intent. If the returned List is not empty,
you can safely use the intent.
Note: You should perform this check when your activity first starts in
case you need to disable the feature that uses the intent before the
user attempts to use it. If you know of a specific app that can handle
the intent, you can also provide a link for the user to download the
app (see how to link to your product on Google Play).
So, you could use that like this:
Intent vlcIntent = new Intent(Intent.ACTION_VIEW);
vlcIntent.setPackage("org.videolan.vlc");
PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(vlcIntent,
PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;
if (isIntentSafe){
startActivity(vlcIntent);
} else {
Intent marketIntent = new Intent(Intent.ACTION_VIEW);
marketIntent.setData(Uri.parse("market://details?id=org.videolan.vlc"));
startActivity(marketIntent);
}
Also, another link that might be useful(VideoLan Wiki):
Android Video Player Intents
It says:
For a simple media playback:
int vlcRequestCode = 42; Uri uri =
Uri.parse("file:///storage/emulated/0/Movies/KUNG FURY Official
Movie.mp4"); Intent vlcIntent = new Intent(Intent.ACTION_VIEW);
vlcIntent.setPackage("org.videolan.vlc");
vlcIntent.setDataAndTypeAndNormalize(uri, "video/*");
vlcIntent.putExtra("title", "Kung Fury");
vlcIntent.putExtra("from_start", false);
vlcIntent.putExtra("position", 90000l);
vlcIntent.putExtra("subtitles_location",
"/sdcard/Movies/Fifty-Fifty.srt"); startActivityForResult(vlcIntent,
vlcRequestCode);
If you specifically want to start VideoPlayerActivity, you can set
vlcIntent.setComponent(new ComponentName("org.videolan.vlc",
"org.videolan.vlc.gui.video.VideoPlayerActivity"));
You could also put the code into a boolean code block and pass in your intent, that way you could reuse the code. Like this:
private boolean checkIntent(Intent intent) {
PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;
return isIntentSafe;
}
You will need to check to see if the package for VLC is installed. If it is not installed then open the play store showing the vlc install page.
This is the source:
String appPackageName = "org.videolan.vlc";
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
The source below will check to see if there is anything that can play video and if not, then it will prompt the user to install VLC. This is a more complete example that might help other users. It checks to see if anything locally installed can play the file and then if not, checks for vlc, and if VLC is not installed, then it will take the user to the Play Store.
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(file));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
intent.setDataAndType(Uri.fromFile(file), mimetype);
PackageManager manager = context.getPackageManager();
List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent, 0);
if (resolveInfoList.size() > 0) {
context.startActivity(intent);
} else {
FragmentManager fragmentManager = ((AppCompatActivity) context).getSupportFragmentManager();
ClassChatRecyclerAdapter.InstallVlcDialogFragment.newInstance(extension).show(fragmentManager, "INSTALL_VLC");
}
This is the dialog that will check for VLC and if it doesn't find it, then it will take the user to the play store to install it. You can take use the try/catch part of the source below to specifically solve your problem.
public static class InstallVlcDialogFragment extends DialogFragment {
public static ClassChatRecyclerAdapter.InstallVlcDialogFragment newInstance(String mediaType) {
ClassChatRecyclerAdapter.InstallVlcDialogFragment frag = new ClassChatRecyclerAdapter.InstallVlcDialogFragment();
Bundle args = new Bundle();
args.putString("mediaType", mediaType);
frag.setArguments(args);
return frag;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String mediaType = getArguments().getString("mediaType");
return new AlertDialog.Builder(getActivity(), R.style.AppDialogTheme)
.setTitle("Unable to find video player for " +mediaType + " files.")
.setMessage("Install VLC Player to play file?")
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String appPackageName = "org.videolan.vlc";
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
dismiss();
}
}
)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dismiss();
}
}
)
.create();
}
}
I'm working on a project that requires the connection of a smartphone to a tablet via a USB cable. To acces the files from the smartphone from the tablet, I am using the Android's Intent.ACTION_GET_CONTENT to retrieve the files. I am, more specifically trying to open pictures.
I know this is possible since, when I click on the notification describing the smartphone, it opens a default Android app with the base folder of the smartphone.
What I am trying to achieve is to directly open the connected smartphone's storage instead of having to switch from the tablet to storage to the smartphone's.
I know how to get the volume name of the smartphone but that hasn't helped me progress. I have checked the Uri, received from the Intent, it is something like content://com.android.mtp.documents/document/951 or content://com.android.mtp.documents/tree/1021.
I have tried to use thes Uri to open the desired folder but it didn't work.
I've tried the new StorageManager API without success.
Recently, I've focused more on trying to simply access the files from my app but using the above mentionned Uri or the mount folder (/dev/bus/usb/001/002/) leads to nothing.
I also tried the Environment.MEDIA_MOUNTED without success.
My current code it this:
Requesting permission to use the smartphone:
final UsbManager manager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
if (deviceList.size() > 0) {//TODO switch to 1 on USBCameraFragment
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
UsbDevice device = (UsbDevice) deviceList.values().toArray()[0];
manager.requestPermission(device, mPermissionIntent);
} else {
Toast.makeText(getContext(), "Please connect your device to the tablet.", Toast.LENGTH_SHORT).show();
}
Opening the connection and starting the Intent:
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
Uri path = MediaStore.Files.getContentUri(device.getProductName());
//Uri path = Uri.parse(Environment.getExternalStoragePublicDirectory(Environment.MEDIA_MOUNTED).getAbsolutePath());
i.setDataAndType(path, "image/*");
i.addCategory(Intent.CATEGORY_OPENABLE);
MtpDevice mtpDevice = new MtpDevice(device);
UsbDeviceConnection conn = ((UsbManager) getActivity().getSystemService(Context.USB_SERVICE)).openDevice(device);
mtpDevice.open(conn);
//1.5s to make sure I have allowed the MTP connection on the smartphone.
try{Thread.sleep(1500);}catch(InterruptedException e){}
startActivityForResult(i, Constants.PICKFILE_REQUEST_CODE);
}
}
else {
Log.d(TAG, "permission denied for device: " + device);
}
}
}
}
};