Check for 3rd party app, open-if not install - android

I am working on a class that when selected by the user should open an application. If that application is not installed they will click the "Find it" button and install it.
Here is what I have so far
public class calc extends Activity {
static final String MARKET_SEARCH_Q_PNAME_PROVIDER = "market://search?q=pname:com.packagename.package";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.getpft);
setTitle("Install Marine PFT?");
((Button) findViewById(R.id.Ok)).setOnClickListener(new Openpft());
((Button) findViewById(R.id.FindIt)).setOnClickListener(new FindZxingOnclickListener());
}
public class FindZxingOnclickListener implements OnClickListener {
public void onClick(View v) {
Intent marketLaunch = new Intent(Intent.ACTION_VIEW);
marketLaunch.setData(Uri.parse(MARKET_SEARCH_Q_PNAME_PROVIDER));
startActivity(marketLaunch);
}}
};
So far the page opens up and it searches correctly for the app. However now that the app is downloaded I need to automatically skip this screen and just open that app. How is that done?

Somehow, you are launching that app. Presumably, you have an Intent that you are passing to startActivity() that does this. If so, you have two choices:
Just call startActivity() and route to your above code in the ActivityNotFoundException catch block
Use PackageManager and queryIntentActivities() to see if anything will respond to your Intent, and if not, route to your above code without calling startActivity() first

Related

Change text content depending on button clicked within the same class

My problem is exactly like this link but it's not in android.
I have one button on a layout and two buttons on an another one. On my application, ClickScreen activity can be triggered by either FirstCase activity or SecondCase activity.
I tried to make a conditional statement on my ClickScreen for which activity is triggered but couldn't handle it. I don't want to create two more classes to do this since it's not an efficient technique.
private void goTo2ndPage() {
Intent i3 = new Intent(this, ClickScreen.class);
startActivity(i3);
}
public class ClickScreen extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.click_screen);
}
}
As we discussed in comments. It looks like what you really want is to add extra data in your intent so that Started Activity can get it and act accordingly.
Check out this post !

Get parameters from android to unity

I have a problem, i want to send a parameter (int) from an app of build in android studio and receive it in an app build it in unity.
The apps work like this, you open the android app, press a botom and open the second app, i send and intent when i open the unity app but idkhow to recieve the param.
I know that are some questions about this but didn't work or maybe idk how to implement it to my code.
This is how i send the param
Java app
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.bodyar");
if(user!=null){
launchIntent.putExtra(Constant.TYPE,user.getLearningStyleId());
}else{
launchIntent.putExtra(Constant.TYPE,Constant.VISUAL);
}
startActivity(launchIntent);
but i dont know how to receive the value. I tried the stuff of UnityPlayer.UnitySendMessage(), but u just get an error from that
And the funciton of the Script that it´s attached to GameObjectUI is this
public void TipoTest(string token){
prueba.text = token;
}
And when i export the unity project to android, in the method OnCreate I recieve the params like this
public class UnityPlayerActivity extends Activity {
protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code
// Setup activity layout
#Override protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
mUnityPlayer = new UnityPlayer(this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
}
#Override protected void onNewIntent(Intent intent) {
// To support deep linking, we need to make sure that the client can get access to
// the last sent intent. The clients access this through a JNI api that allows them
// to get the intent set on launch. To update that after launch we have to manually
// replace the intent with the one caught here.
setIntent(intent);
}
}
And It works but idk how to pass the variable to unity script

All apps associated with this action have been disabled, blocked, or are not installed Storage Access Framework

In my application I am trying to get MS-Word and PDF files through Storage Access Framework which works well on some devices I've tested upon but on Samsung note 4 API 6 I am getting an error
All apps associated with this action have been disabled, blocked, or
are not installed
Code:
warantyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/pdf,application/msword");
Intent i = Intent.createChooser(intent, "File");
getActivity().startActivityForResult(i, FILE_REQ_CODE);
}
});
I'm not sure if this is directly related to your issue, but it is related to an issue I personally had with this error when using Intents (Incorrectly). I have received this error when attempting to declare an Intent globally. For example:
public class MyClass{
// Class Variables (BAD)
private Intent someActivity = new Intent(this, SomeClass.class);
#Override
protected void onCreate(Bundle savedInstanceState){
// Some Code
}
}
Then, I found that this issue was resolved when I did this:
public class MyClass{
// Class Variables (Not Bad)
private Intent someActivity;
#Override
protected void onCreate(Bundle savedInstanceState){
someActivity = new Intent(this, SomeClass.class);
}
}
If this doesn't help you in your specific situation, I hope this helps someone at some point.
When debugging to find the reason behind this problem, I couldn't see any note of the Toast that generated the text "All apps associated with this action have been disabled, blocked, or are not installed." There was no trace of this being an "error." It seems to me more of an OS-handled exception for incorrect usage of Intents.
Since setType() method of Intent takes one argument as String i.e MIME type and its compulsary because based on the MIME type requested android system finds all actions that are supported.
For example if you want to choose any type of content then you can simply write setType("*/*").

How to always start from a startup activity on Android?

There are three different cases:
1) A user launches an app, navigates in it, pressed home and click on the app icon again to launch our app again.
2) A user launches an app, navigates in it, presses home, chooses recent and click on the app to launch our app again.
3) A user launches an app, navigates in it, click something in the app (TextView with a link), which calls another app (as example Email) and user clicks back button, which bring us back to our app.
I know about flag "clearTaskOnLaunch" flag, it solves case #1.
I know about about flag "excludeFromRecents", it solves case #2 (may be not the most user friendly solution, but it works).
What about case #3? I have a workaround right now. However, I will have to put it on all activities which can be lead to another app. I wonder, whether there is better way to solve it (without handling it in all such activities).
This should be handled on the Application level.
For API level 14, you can register an ActivityLifeCycleCallback in your Application class
public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)
You can use it, to know on an Application level, which activities are destroyed, paused, resumed etc etc. Whenever, an activity is paused, without a new activity being created/resumed, you should clear the Activity stack, and re-launch your startActivity
If you target SDK versions < 14, you should implement your own method, to know which activities are created/resumed and paused, and do the same whenever an activity is paused, without a new activity being created/resumed
1) define a public static normalPause = true variable in a Class.
2) in onPause method of all of your activities set it false (I am worry. We might not be in a normal pause)
2) in onCreate method of all of your activities set it true (Do not worry. We are in a normal pause)
3) in onResume of all of your Activities:
if(!Utilities.normalPause)
{
this.finish()
}
Enjoy!
It seems a similar question has already been asked. It sounds like the OP came up with a working solution. How do I collapse "child activities"?
EDIT:
Instead of using a button you can use a boolean to tell whether or not you need to collapse back to the main activity. Have your root activity extend from Activity and the child activities extend from CollapsableActivity. To get this to work in all cases I added startOutsideActivity() and startOutsideActivityForResult().
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class CollapsableActivity extends Activity {
private boolean returnToRoot;
public static final int COLLAPSE_BACK = -1; // something other than RESULT_CANEL (0)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
returnToRoot = true;
}
#Override
protected void onStart() {
super.onStart();
returnToRoot = true;
}
#Override
protected void onRestart() {
super.onRestart();
// start collapsing the stack
if (returnToRoot) {
setResult(COLLAPSE_BACK);
finish();
}
}
#Override
public void startActivityForResult(Intent intent, int requestCode) {
super.startActivityForResult(intent, requestCode);
returnToRoot = false;
}
public void startOutsideActivityForResult(Intent intent, int requestCode) {
super.startActivityForResult(intent, requestCode);
returnToRoot = true;
}
#Override
public void startActivity(Intent intent) {
// call startActivityForResult to make sure and catch the collapse condition
super.startActivityForResult(intent, 0);
returnToRoot = false;
}
public void startOutsideActivity(Intent intent) {
super.startActivity(intent);
returnToRoot = true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == COLLAPSE_BACK) {
returnToRoot = true;
}
}
}
This worked properly for me in all cases you listed. The only difference is you need to call startOutsideActivity() or startOutsideActivityForResult() when you navigate away from you app. Personally, I think this adds clarity to your intentions. Hope it helps!
I know you don't want to manage it in all activities but you can do this and still handle the code in one place with a super activity
public abstract class BlundellActivity extends Activity {
#Override
public void onPause(){
// Whatever strategy you want
}
}
public class SomeActivity extends BlundellActivity {
// Do whatever you normally want to do
}
public class SomeActivity extends BlundellActivity {
// Do whatever you normally want to do here as well
}
Perhaps, android:noHistory is what you're looking for. If you declare all your activities except StartupActivity with this attribute, then they will be finished as the user navigates away from them and only StartupActivity will appear.
You can try this steps:
use one boolean static flag isFinish in StartupActivity with default false value.
in onCreate() of StartupActivity set isFinish value to false.
write below code in onResume() method of all activities in your project.
if(isFinish)
{
finish();
}
set isFinish value to true when you open any native app like email, browser etc.
or
5 . set isFinish value to true in onBackPress() method whenever you want to close application on back press.
Case 6: if android browser open on clicking on any link then use below code is onPause() method
if(isBrowserRunning("com.android.browser"))
{
isFinish = true;
finish();
}
////////////////
private boolean isBrowserRunning(String processName)
{
ActivityManager manager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
String packageName = manager.getRunningTasks(1).get(0).topActivity.getPackageName();
Log.i("LogTest", "Current process package name: " + packageName);
return processName.equalsIgnoreCase(packageName);
}
You can create a sample project to know other browser package name like opera mini, US browser etc.
add below permission in manifest:
<uses-permission
android:name="android.permission.GET_TASKS" />
You can call this.finish() on the onPause() of your Activity, that way the activity will be closed in the three cases.
You need to use bundle and pass appropriate parameter/or parameters from the calling app (i.e. click something in the app (TextView with a link)).
Retrieve the parameter in the called app (Email app).
You can send the name of the activity in the parameter.
Now being in Email app(the called app) Click of back button navigate back to your calling application.
Optionally you can save the state of activity from the caller program, as required.
You need to use Bundle, and Intent to implement this logic.
Code snippet:
In the calling program, we need to store parameters/data required for back button functionality in the called program.
Bundle bndleData = new Bundle();
Use putString(), putInt() methods of Bundle class.
String prefix = getPackageName().toString();
(this prefix can be stored in application level constants.java file as applicable)
bndleData.putString("ParentActivity", this.getLocalClassName());
Also store additional parameters if required
bndleData.putString("paramName", valueofParamName);
bndleData.putInt("IntChannelImage", chImageInt);
Intent intent = new Intent(v.getContext(), AMRChannelPlayer.class);
intent.putExtra(prefix + "bndleChnlData", bndleData);
startActivity(intent);
Caller Program:
Retrive the data, activity nae from bundle and use it in back button implementation:
prefix = getPackageName().toString();
Bundle extras = getIntent().getBundleExtra(prefix + "bndleData");
String parentActivity = extras.getString("ParentActivity");
extras.getString("paramName");
I hope this helps you.
Instead of using multiple solutions you can use a single one that solves all the problems.
Check this answer:
https://stackoverflow.com/a/8576529/327011
With a Broadcast and BroadcastReceivers in each activities of your application you can kill all activities whenever your application goes to background.
UPDATE:
To detect if your application when to background you can use onStop, check this to understand the theory: Activity side-by-side lifecycle
And this is the implementation: https://stackoverflow.com/a/5862048/327011
I think this is all you need :-)

Notification opens activity, press back button, prevent opening back stack activity?

This looks very similar to my previous question because it's some sort of follow up. I was not very happy with the only solution given; also, the solution was for a problem slightly different from this one. So let me try to explain the problem again...
A notification is created at boot (with a BroadcastReceiver).
My app main activity is opened and the home button is pressed (the activity will be sent to the back stack).
I pull down the status bar and press on the notification previously created at boot.
That will start some activity, different from the main one.
I press the back button and the main activity is displayed.
This is not very different from my previous question... The thing is, "main activity" was just an example. I could have opened the app main activity and then opened the about activity through a menu option and pressed the home button. The back stack would now be MainActivity » AboutActivity. Which means that when the back button is pressed while in "some activity" (started by pressing the notification), we would be brought to the top of the back stack, that is, the about activity.
What basically want is to prevent any other activity to be opened when I press the back button while in "some activity" (again, started by pressing the notification). I want to be brought exactly where I was, that could be the desktop or some other app's activity, but not my app's MainActivity nor AboutAcitivity cause that's not where I was, those were in the back stack, "sleeping" in the background.
I have come up with a solution, but I don't think it's very elegant and I was looking for something more, well, elegant... If you have any other suggestion, please, let me know.
Anyway, this is my proposed solution:
// I use this class for public static (or public static final) members and
// methods
public final class AppHelper {
public static final String KEY_RESUME_FROM_NOTIFICATION = "resumeFromNotification";
private static boolean sResumeFromNotification = false;
public static boolean getResumeFromNotification() {
return sResumeFromNotification;
}
public static void setResumeFromNotification(boolean resumeFromNotification) {
sResumeFromNotification = resumeFromNotification;
}
}
public class MainActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
(...)
}
#Override
protected void onResume() {
super.onResume();
if(AppHelper.getResumeFromNotification()) {
AppHelper.setResumeFromNotification(false);
moveTaskToBack(true);
}
}
}
public class AboutActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
(...)
}
#Override
protected void onResume() {
super.onResume();
if(AppHelper.getResumeFromNotification()) {
AppHelper.setResumeFromNotification(false);
moveTaskToBack(true);
}
}
}
public class SomeActivity extends Activity {
// This will be called when the notification is pressed and the activity is
// not opened yet
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
(...)
extractIntentExtras(intent);
}
// This will be called if the activity is already opened and the
// notification is pressed
#Override
protected void onNewIntent(Intent intent) {
extractIntentExtras(intent);
super.onNewIntent(intent);
}
private void extractIntentExtras(Intent intent) {
Bundle bundleExtras = intent.getExtras();
if(bundleExtras != null) {
// These intent extras are set on the Intent that starts this activity
// when the notification is pressed
AppHelper.setResumeFromNotification(bundleExtras.getBoolean(
AppHelper.KEY_RESUME_FROM_NOTIFICATION));
mRowId = bundleExtras.getLong(AgendaNotesAdapter.KEY_ROW_ID);
populateNoteUpdateFields();
}
}
}
I don't know, but this solution doesn't look very elegant to me (but it works as I expect it) and I'm looking for alternatives or for strong opinions on my proposed solution as an acceptable and good solution. Thoughts?
After doing some more reading perhaps this is the combination of flags you need:
Intent intent = new Intent(mContext, SomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);
I think that should force your SomeActivity class to be launched in a completely new task.
When launching the Activity from the notification, you can control how the Activity you are about to open is put on the back stack, and what task it's associated with with Intent flags. You can try something like:
Intent intent = new Intent(mContext, SomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
If that doesn't work, try setting a few of the other flags until you get the desired behavior.
Do you ever want your MainActivity to stay in history? If not then my simple, crude solution is to finish the MainActivity when it is paused.
(Call this in your MainActivity)
#Override
public void onPause() {
finish();
}
This will ensure that your MainActivity is removed from history when you navigate away from it, and will never appear when the back button is pressed.
This could be used for AboutActivity as well.

Categories

Resources