I am creating 'my own launcher. In that case I want to putQuick search bar` in my home screen i.e. Google now launcher.
How can I do that. I have gone through multiple threads but not found any relevant answer.
I don't want to show the widget picker.I want asap user install this launcher search bar should be there.
Thanks in advance.
I really recommend you to clone Launcher3 repository from AOSP.
https://android.googlesource.com/platform/packages/apps/Launcher3/
If you checkout nougat-mr5 branch you can look at the code to show searchbar by taking the component from GMS package and including it as a row element. Please look for QSB in the code.
The search bar is not displayed because the launcher doesn't have permissions to show the widget.
As you probably already figured out, if a user explicitly adds the search bar widget to any screen, he will be prompted to give the permission, and the search bar on top also appears.
The problem is that getOrCreateQsbBar method in Launcher class (I assume you forked Launcher3) doesn't ask for permissions if it can't instantiate the widget, it instead silently fails. The problem is in this snippet inside of getOrCreateQsbBar:
if (!AppWidgetManagerCompat.getInstance(this)
.bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {
mAppWidgetHost.deleteAppWidgetId(widgetId);
widgetId = -1;
}
Instead of just resetting widgetId to -1 you want to ask for permissions to install the widget and call getOrCreateQsbBar again. Here's an example code that asks for permission:
boolean hasPermission = appWidgetManager.bindAppWidgetIdIfAllowed(widgetId, searchProvider);
if (!hasPermission)
{
mAppWidgetHost.deleteAppWidgetId(widgetId);
widgetId = -1;
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, searchProvider);
startActivityForResult(intent, REQUEST_BIND);
}
Then overload onActivityResult in the Launcher class, something along the lines of:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_BIND) {
mSearchDropTargetBar.setQsbSearchBar(getOrCreateQsbBar());
}
}
Related
I am in a fragment which is a feedback form. When the user clicks on the button it takes the data from the form and passes it to an e-mail program that gets open after the user chooses it from the list after startActivity(intent).
My problem is, I am not sure if there is a way to get feedback to know when the 3rd party mailer is done or if the launcher is cancelled.
Also in my example, if you click the submit and then click on the gmail and then click send in gmail and close it out, it brings you back to the app with all the data still on the form.
I would like to switch fragments to a thank you fragment. I did experiment and was happy that if you click on a different icon int the bottom nav bar and go back to the feedback fragment that all the data is cleared out.
Thank you and all help would be appreciative.
Shawn Mulligan
P.S. There is no code as I don't feel it is needed, I just need to know what direction to go into and any code snippetts if available to do the next step. change fragments after intent.
public void sendFeedbackMessage(String subject, String message) {
Intent messageIntent = new Intent(android.content.Intent.ACTION_SENDTO);
messageIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
messageIntent.setType("plain/text");
messageIntent.putExtra(android.content.Intent.EXTRA_TEXT, message);
messageIntent.setData(Uri.parse("mailto:foo#gmail.com"));
startActivity(messageIntent);
}
startActivityForResult(messageIntent,1000);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
if (requestCode == 1000){
Toast.makeText(getContext().getApplicationContext(),"You sent mail",Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(getContext().getApplicationContext(),"Mail Not Sent",Toast.LENGTH_SHORT).show();
}
}
So I looked into startActivityForResult and onActivityResult and changed my code to the above. However it is doing nothing but Mail Not Sent. I did find out that gmail for one does not support this. I am totally fine with this, but shouldn't the chooser itself return something so that way the app would know if an app was chosen or the cancel or back button was used?
I have created an android app for the Portuguese (Brasil). This is one of my client's app. The client is getting feedback from the app users that they are not able to use the app properly or it goes back to start screen when they click on the button to import a contact from the Phonebook.
i.e. In the app, there are various places where I start the activity to get the result.
startActivityForResult(intent, requestCode);
Generally, I'm doing this from Fragments. And to pass the result from Activity to its Fragment, I'm doing like following:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (getSupportFragmentManager() != null) {
Fragment fragment = getFragment();
if (fragment != null)
fragment.onActivityResult(requestCode, resultCode, data);
}
}
So to check this problem We asked some of the users to check if they have Developer options enabled on their device. And Yes, they have it enabled on their devices. So we asked them to disable this and try the app and believe me it works.
I also have this option enabled on my device to test the app (Debugging) and I haven't faced any problem like this while using the app.
I don't understand this issue and I need to find the appropriate solution.
So I need your help to solve this problem.
Looking for the positive responses.
Thanks.
Try fragment context instead of getActivity() as you are starting activity from the fragment and result should be returnned to fragment.
Intent intent=new Intent(fragment.getContext(), Activity.class)
fragment.startActivityForResult(intent,REQUEST_CODE);
Finally, after a very long time, the issue is resolved.
When we have Don't keep Activities option enabled on the device and as soon as you leave the activity, it gets destroyed.
And in the onCreate, I was adding the initial fragment again.
But now I have added a check of
if(savedInstanceState == null)
// initial fragment here
else
// nothing to do
This check resolved the issue in my app. Hope it helps the others too.
I'm trying to open a pdf file from my app , on my device currently installed 3 3rd party apps to open pdf file. when the system asks me on witch of them to open the pdf, how can i know if the user selects one and presses "ok" or "decline"? my actions defined by if he accepts or declines
This is in my class :
String path="...../file.pdf";
Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(path)), "application/pdf");
startActivityForResult(intent, 225);
And then in the activity :
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == 225) {
// Make sure the request was successful if (resultCode == RESULT_OK)
} else {
}
}
screen shot for example
You can find all of the apps on the device that can service your Intent using the following code:
List<ResolveInfo> pkgAppsList = context.getPackageManager().queryIntentActivities( mainIntent, 0);
You can use the information from this to query the packages and learn their display name and icons (SO has plenty of answers how to do that).
You can create your own Dialog from within your app that looks identical to the system dialog. In this way you'll be able to track hits and pass the intent to the selected package directly.
Good luck!
how can i know if the user selects one and presses "ok" or "decline"?
You can't. ACTION_VIEW that is used to open a pdf in an external app does not give back any information. You can use startActivityForResult() but it will not have any effect because a result will not be set. Also see ACTION_VIEW documentation.
You should redesign your concept/logic so that it does not depend on this information.
There are a lot of questions out there on similar topics, but after searching around I haven't found one that matches my issue.
I know about starting intents for result, and overriding onActivityResult() to handle these intents, but for some reason, I'm having issues when I'm coming back from activity b to activity a. So, for example, in the last of 3 activities (AddDirections class) I start in my project, I call this method to return back to the previous activity:
public void finish(View v){
Intent intent = new Intent(getApplicationContext(), AddIngredients.class);
intent.putExtra(Home.RECIPE_INTENT, (Parcelable)recipe);
intent.putExtra(Home.RECIPE_ID_INTENT, recipe.getId());
setResult(RESULT_OK, intent);
finish();
}
In the AddIngredients class, I have this method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK && requestCode == DIRECTIONS_REQUEST){
Intent intent = new Intent(getApplicationContext(), NameRecipe.class);
Recipe recipe = data.getParcelableExtra(Home.RECIPE_INTENT);
intent.putExtra(Home.RECIPE_INTENT, (Parcelable)recipe);
setResult(RESULT_OK, intent);
finish();
}
}
This should accept the returned result from the AddDirections class, and pass it off to NameRecipe, where I have the exact same method (Except for in the new Intent method it says Home.class). In the Home class, I have basically the same method again to receive the intent as it backs all the way out of the app.
Now, I will say that this works if I go straight through the steps from beginning to end. But if I use the up navigation to go the current activity's parent activity, then it messes everything up. Then when I click finish in the final step it messes up the resultCodes that I set for each intent. I make sure to explicitly set the correct result to RESULT_OK (which equals 1) but then for some reason, sometimes it changes what I've set to be the resultCode to be 0 instead.
Here's what I do in an activity if the user clicks the up navigation:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = NavUtils.getParentActivityIntent(this);
intent.putExtra(Home.RECIPE_INTENT, (Parcelable)recipe);
setResult(RESULT_OK, intent);
NavUtils.navigateUpTo(this, intent);
finish(); //Have tried with and without this
return true;
}
return super.onOptionsItemSelected(item);
}
Like I said, I've searched for a lot of reasons why the resultCode gets overwritten after using the up navigation, but I haven't found a single reason why.
Any help would be greatly appreciated.
It looks like the underlying question is really how do I navigate between multiple activities through the stack using the up navigation that is built in. I am wondering if the project is setup correctly for this type of navigation. From the android developer resources, up navigation from google, you have to setup the navigation buttons with a parent activity. Then the application can traverse between the different activities. From what it looks like this should allow A->B B->C c->D and back to A if needed. I would also add in a button that would allow a direct path back to A if the user so chooses.
If you have more information on what you are trying to accomplish between activities whether it is data passed back and forth or just returning to the previous activity that would be helpful. Hopefully the link will help your issue with this.
your problem seems to be the NavUp, this util class tends to clear everything to navigate to the parent including your resultCode and the instance of the activity, resulting in a Canceled result (if started for result) to a new instance of the parent activity, in order to fix that a quick fix would be to declare android:launchMode="singleTop" in your manifest, but I wouldn't recommend to use that unless you are 100% that you want that, instead I would go into my navigator class, or my method for navigate and overwrite that specific navigation to something like:
Intent parentActivityIntent = NavUtils.getParentActivityIntent(this);
parentActivityIntent.setFlags(
Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP
);
NavUtils.navigateUpTo(this, parentActivityIntent);
Hope this helps!!
Sorry for the late answer :p
if by 'up navigation' you mean back key pressed then you need to override a function
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
}
if from what it seems to be you are trying to get back when clicking an item from the Options Menu to your parent activity directly then i think you will need to go back step by step as at this moment there is already an activity running and waiting for a result so when you go directly to home activity its already waiting an answer from activity B and not activity C i hope i explained it right :)
What I would like to do is the following:
User selects a shortcut from a list of all available shortcuts in the system;
The relevant info is stored;
User performs an action and the selected shortcut is executed, like if it was an icon on the home screen.
So far I am able to populate and present a list with all the shortcuts, using
getPackageManager().queryIntentActivities(new Intent(Intent.ACTION_CREATE_SHORTCUT), 0);. Upon selecting a shortcut, I start the ACTION_CREATE_SHORTCUT intent to customize the shortcut parameters - it presents the proper UI and seems to work. I use this code to start the intent:
ActivityInfo activity = resolveInfo.activityInfo;
ComponentName name = new ComponentName(activity.applicationInfo.packageName, activity.name);
Intent i = new Intent(Intent.ACTION_CREATE_SHORTCUT);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
i.setComponent(name);
startActivityForResult(i, 1);
Here is my onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode==1 && resultCode == RESULT_OK) {
try {
startActivity((Intent) data.getExtras().get(Intent.EXTRA_SHORTCUT_INTENT));
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Success!!", Toast.LENGTH_LONG).show();
finish();
}else{
Toast.makeText(getApplicationContext(), "Fail: "+resultCode+" "+resultCode, Toast.LENGTH_LONG).show();
}
super.onActivityResult(requestCode, resultCode, data);
}
Now, the problem is that the onActivityResult always gets triggered immediately after startActivityForResult with requestCode=0, resultCode=0 and with no data. It does not trigger when the ACTION_CREATE_SHORTCUT activity actually ends. I really don't get it. I think that after the activity ends it should return the requestCode I sent it and the data intent, containing the Intent.EXTRA_SHORTCUT_INTENT which I could then use somehow to actually start the shortcut.
The second part of the question is how do I actually store the necessary information for the shortcut the user selected, preferably in SharedPreferences, so I could later execute this shortcut with the specific parameters. I couldn't find any example of this.
Any help would be much appreciated! Thanks!
More then 2 years later, here is the answer to my question:
The proper functioning of the startActivityForResult/onActivityResult system obviously depends on both the calling and the called Activities being part of the same Task. Therefore any action which would cause the two activities to be launched in separate Tasks would break this functionality. Such actions include setting any exclusive launchMode for any of the Activities in the AndroidManifest.xml or using flags such as Intent.FLAG_ACTIVITY_NEW_TASK when launching any of the two Activities.
Upvoted the answer of user2427931 for the Intent.parseUri() solution.
I had the same behavior when my calling activity had launchMode="singleInstance". Do you have that defined as well?
Regarding saving the Intents. You could turn the intent into an URI and save it as a string in SharedPreferences. You could then use Intent.pareseUri() once you have retrieved it.
//Erty