Simple enough,
At the top left hand corner of the action bar sits the default icon for the application. In most apps, it is clicked and returns you to the homepage. I'm working with 2 devices, a 3.2 and a 2.3.3 and I am trying to implement the action bar on the 3.2 without affecting the other.
I imagine its implemented like this:
case android.R.id.home:
Intent intent = new Intent(this, ActOnThisActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
One last thing is to set the flag
getActionBar().setHomeButtonEnabled(true);
This should work but as anyone familiar with android will know, this cant be run on an API of 11 or below. So it will run on 3.2+ but not the 2.3.3. Is there a way to specify this method to only work on api11 and above?
NOTE that #TargetApi(11) annotation might work but I've had some weird errors with it.
Is there a way to specify this method to only work on api11 and above?
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setHomeButtonEnabled(true);
}
Taking a look at ActionBarCompat from the sdk samples will give you fair idea of how to do it.
The following code in the ActionBarHelper class(from the sample) decides the instance for different versions.
public static ActionBarHelper createInstance(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return new ActionBarHelperICS(activity);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
return new ActionBarHelperHoneycomb(activity);
} else {
return new ActionBarHelperBase(activity);
}
}
Have a look at ActionbarSherlock - I use it in a few apps and it works flawlessly. Mimics the Action Bar perfectly in Android versions below Honeycomb (3.0).
http://actionbarsherlock.com/
Main API for nearly all interaction with the action bar. This is the exact API getSupportActionBar() exposes.
Related
Window window = MainActivity.this.getWindow();
window.setStatusBarColor(MY_COLOR_IT_CAN_BE_ANY);
if (Build.VERSION.SDK_INT < 30)
{
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
else {
window.setDecorFitsSystemWindows(false);
WindowInsetsController controller = getWindow().getInsetsController();
if(controller != null) {
controller.setSystemBarsAppearance(WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
}
}
I am using this code for setting light status bar in android 11 and below android 11. Everything works fine, just a little problem, deprecation warning not going.
deprecation warning is showing when you use deprecated code and you are not - you have proper if statemnent, causing using not-yet-deprecated methods on < 30 and new method on 30+
if(fullScreen)
{
getWindow().getDecorView().getWindowInsetsController().hide(WindowInsets.Type.statusBars());
getWindow().getDecorView().getWindowInsetsController().setSystemBarsBehavior(BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}
else
{
getWindow().getDecorView().getWindowInsetsController().show(WindowInsets.Type.statusBars());
getWindow().getDecorView().getWindowInsetsController().setSystemBarsBehavior(BEHAVIOR_SHOW_BARS_BY_SWIPE);
}
Above code used for full screen from Android 11, it's important to set setSystemBarsBehavior(BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) else on swipe down status bar get display and does not disappear till activity is not recreated.
I just did one thing, since my if statement is fine, I just suppressed warning by using
#SuppressWarnings("deprecation")
I just used this annotation for that particular method which contains this code.
There is another option present which is also perfectly fine:
just add
//noinspection deprecation
above line of code which is deprecated. This will allow to check other warnings in that whole function. Which is good and I will prefer.
What is the advantage of //noinspection deprecation over #SuppressWarnings("deprecation")?
This prevents the problem with #SupressWarnings, which is it ignores all warnings in the method. So if you have something deprecated that you are not aware of, #SupressWarnings will hide it and you will not be warned. That is the advantage of the //noinspection
Courtest and check more details in this post answers:
How to suppress specific Lint warning for deprecated Android function?
I am working on stripe-terminal-android-app, to connect to BBPOS 2X Reader device,
wanted to click-item from list,(recyclerView).
I am trying to do:
when list of devices appears(readers), I am checking if readers.size()==1, then click first-device from list,else show recyclerView();
I have very less experience in Android(coming from JS, PY), :)
After going through debugger to understand flow of program-running, I used F8 key, or stepOver the functions one by one,
and where value is assigned to convert in displayble-format in adapter as here.
public ReaderAdapter(#NotNull DiscoveryViewModel viewModel) {
super();
this.viewModel = viewModel;
if (viewModel.readers.getValue() == null) {
readers = new ArrayList<>();
} else {
readers = viewModel.readers.getValue();
if(readers.size() == 1){
Log.e(TAG, "readers.size() is 1 "+ readers.size());
}
}
}
then in ReaderHolder-file, values are bind() as
void bind(#NotNull Reader reader) {
binding.setItem(reader);
binding.setHandler(clickListener);
binding.executePendingBindings();
}
}
I tried assigining button and manually clicking when only-one device appears, by clicing on reader[0], can't do that by findViewById inside Adapter file, to call onClick() method manually,
I tired another StackOverflow's answer but didn't understood, from here.
Main fragment is discovery-fragment,
how can I click first-device by checking readers.size()==1, then click onClick()?
my final-goal is to automate, whole stripe-terminal-payment process on android.
extra-info:
I am fetching data from python-odoo server, then using url, will open app through browser, (done this part), then device will be selected automatically as everytime-no any devices will be present except one,
so will automatically select that from recyclerView, then proceed.
I have asked for help in detailed way on GitHub-issues, and started learning Android's concepts for this app(by customizing stripe's demo app, which works great, but I wanted to avoid manually clicking/selection of devices).
Since my Google Maps app updated recently, now version 10.11.1, the following code does not show the label as expected, documented, and previously working:
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("geo:38.8951,100.0364?q=38.8951,100.0364(foo)")).setPackage("com.google.android.apps.maps")
if (intent.resolveActivity(packageManager) == null) {
intent.setPackage(null)
}
startActivity(intent)
And neither does this version (with 0,0 immediately after geo:):
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=38.8951,100.0364(foo)")).setPackage("com.google.android.apps.maps")
if (intent.resolveActivity(packageManager) == null) {
intent.setPackage(null)
}
startActivity(intent)
Neither does the example code in the official documentation show a label:
// Display a label at the location of Google's Sydney office
Uri gmmIntentUri = Uri.parse("geo:0,0?q=-33.8666,151.1957(Google+Sydney)");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
Update: Scheduled to be fixed in v11.12 perhaps before the end of January 2022.
No solution still even with latest map update 10.12.1 the label still does not show even if the documentation still says it should
I've created an issue on Google's Issue tracker: https://issuetracker.google.com/issues/129726279
hopefully we'll have some information shortly.
Per Google, it's a bug in the Google Maps app. It's fixed in version 11.12.
I think we are going about it the wrong way here. If I was Google, I would also feel insecure about allowing developers to post directions with an abstract destination label, I am sure they never plan to fix this.
I recommend the following solution according to Google's new standards. https://developers.google.com/maps/documentation/urls/android-intents:
https://www.google.com/maps/dir/?api=1&destination=LATITUDE,LONGITUDE
If you look at most apps these days, including the ones I have built, this allows us to post a LAT/LONG for the user to go to with Google's own Address values built in as the destination label.
To actually launch the Google Maps application, simply launch a web intent, I use the application context in this case.
fun startGoogleMaps(context: Context, lat: Double, long: Double) {
startWebBrowser(
context,
Uri.parse("https://www.google.com/maps/dir/?api=1&destination=$lat,$long")
)
}
fun startWebBrowser(context: Context, link: Uri?) {
if (link != null) {
val webIntent = Intent(Intent.ACTION_VIEW, link).apply {
addFlags(FLAG_ACTIVITY_NEW_TASK)
}
if (webIntent.resolveActivity(context.packageManager) != null) {
context.startActivity(webIntent)
}
}
}
I'm trying to make an Activity Transition using Shared Elements on a pre-Lollipop device (4.x). Is it possible? So far, I'm trying this:
public class RewardDetail extends ActionBarActivity {
#Override
public void onCreate(final Bundle savedInstanceState) {
...
ViewCompat.setTransitionName(imageView, TRANSITION_NAME);
}
...
public static void launch(ActionBarActivity activity, View transitionView, WelcomeReward detailData) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, transitionView, TRANSITION_NAME);
Intent intent = new Intent(activity, RewardDetail.class);
intent.putExtra(PARAM_DATA, detailData);
ActivityCompat.startActivity(activity, intent, options.toBundle());
}
}
called by:
#Override
public void onClick(final View v) {
int position = recyclerView.getChildPosition(v);
WelcomeReward welcomeReward = data.get(position);
RewardDetail.launch(WelcomeRewardActivity.this, v.findViewById(R.id.reward_view), welcomeReward);
}
But it results in a "regular" transition (no shared element). Any ideas?
EDIT
According to this video, it could be done:
https://www.youtube.com/watch?v=RhiPJByIMrM&index=8&list=WL
Is there a library already implementing this for pre Lollipop ?
No, Activity/Fragment Transitions are not possible on pre-Lollipop devices. According to the documentation:
Start an activity with additional launch information, if able.
In Android 4.1+ additional options were introduced to allow for more control on activity launch animations. Applications can use this method along with ActivityOptionsCompat to use these animations when available. When run on versions of the platform where this feature does not exist the activity will be launched normally.
See also George Mount's answer to this StackOverflow question.
You can check out this library for activity and fragment transitions for pre lollipop devices
dependencies {
compile 'com.albinmathew:PreLollipopTransition:1.1.2'
}
https://github.com/albinmathew/PreLollipopTransition
Although the fancy Lollipop Activity/Fragment transitions are not available pre-Lollipop (without the use of a 3rd party library), you can still override the animation used to transition between activities.
Just before/after you start invoke startActivity() you can make a call to [Activity.overridePendingTransition](http://developer.android.com/reference/android/app/Activity.html#overridePendingTransition(int, int)). When you leave your activity, call the same method.
Similarly you can use ActivityOptionsCompat to define a custom animation to use during a transition.
ActivityOptionsCompat opts =
ActivityOptionsCompat.makeCustomAnimation(getActivity(), R.anim.in, R.anim.out);
startActivity(intent, opts.toBundle());
There is a support library, but it does not support (all) transitions on Android versions below 5.0. There are however some alternatives:
Unofficial Compatibility libraries https://github.com/andkulikov/transitions-everywhere
https://github.com/takahirom/PreLollipopTransition
https://github.com/lgvalle/Material-Animations
Android KitKat http://www.doubleencore.com/2013/11/new-transitions-framework/ and a
sample found in your SDK samples folder.
Posted earlier to a duplicate of this question here: https://stackoverflow.com/a/27344471/1683141
I am currently developing an app and I would like to have a little more control over it then usual without having to root the device.
I would like to remove the capability of the recent apps button in the navigation bar, or at least make it do something else from the default actions. Is there a way to do this? I'm sure there is since SureLock does the same thing.
Thanks
I have found a workaround for this on this website:http://www.juliencavandoli.com/how-to-disable-recent-apps-dialog-on-long-press-home-button/
you need to add this permission: android.permission.REORDER_TASKS
And add this code:
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
if( !hasFocus)
{
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
am.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_WITH_HOME );
sendBroadcast( new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS) );
}
}
It is not possible to override the recent apps button.
There is no KeyEvent like there is for the Back Button, and as such this feature is not available.
See documentation here: http://developer.android.com/reference/android/view/KeyEvent.html
You may not be able to disable a button, but you can disable the app that is associated with it. I don't know how it is done, but I have seen kiosk app (for non-rooted devices) that disallow other apps from loading.