The minimum Youtube App. version required to be installed on a device to use the Youtube API is 4.2.16
To get the youtube app. version installed on a device:
String version = YouTubeIntents.getInstalledYouTubeVersionName(getContext());
Thats could return as known a three numbers separeted by dots. How can I check if the returned version number is less than 4.2.16. Which is obviously not an integer and not a floating point number?
Accepted for the ##Original answer:
Original answer:
Well, this may not be the easiest way, but you can do something like this:
First split the string at the .'s:
String[] partsOfVersion = version.split("\\.");
Then convert each part into an int:
int first = partsOfVersion.length>0 ? Integer.parseInt(partsOfVersion[0]) : 0;
int second = partsOfVersion.length>1 ? Integer.parseInt(partsOfVersion[1]) : 0;
int third = partsOfVersion.length>2 ? Integer.parseInt(partsOfVersion[2]) : 0;
Then you can just use an if statement to check if they're above 4.2.16:
if((first == 4 && second == 2 && third >= 16) || (first == 4 && second >== 3) || first >= 5) {
...
}
And if you want to check if it's less than that, just use an else statement after that if statement.
That should work, I haven't tested it though.
Added:
Someone (#JeroenVannevel) pointed out to me that there's an easier way to do this.
First remove all occurrences of .:
version = version.replace(".", "");
Then convert the string to an int:
int versionInt = Integer.parseInt(version);
And finally, check if the number is greater than or equal to (or less than if you want incompatible devices) 4216:
if(versionInt >= 4216) {
...
}
Also, you might want to check if version is empty or not before starting.
the answer to your problem is very simple, as you see from AndroidManifest.xml file to
YouTube 4.2.16 android apk I found this line .
<manifest android:versionCode="4216" android:versionName="4.2.16" package="com.google.android.youtube" ...>
so to check if app you need to do to check if the VersionCode biger than int (4216) by Public methods
getInstalledYouTubeVersionCode(Context context)
for more info visit YouTubeIntents Reference Guide.
In final you can use this ready check
if(YouTubeIntents.isYouTubeInstalled(getActivity()) && YouTubeIntents.getInstalledYouTubeVersionCode(getActivity())>4216){
//do what you want whit YouTubeIntents
}else {
//Ask user to install the last youtube app .
}
I hope this answer help you.
I wrote a class for precisely this purpose, maybe it could be useful.
public class Version implements Comparable<Version>
{
public final int Major;
public final int Minor;
public final int Build;
public final int Revision;
public Version(int major, int minor)
{
this(major, minor, 0);
}
public Version(int major, int minor, int build)
{
this(major, minor, build, 0);
}
public Version(int major, int minor, int build, int revision)
{
Major = major;
Minor = minor;
Build = build;
Revision = revision;
}
public Version(String str)
{
int major = 0;
int minor = 0;
int build = 0;
int revision = 0;
if (Strings.hasValue(str))
{
String[] parts = str.split("\\.");
if (parts.length > 0)
major = parseInt(parts[0]);
if (parts.length > 1)
minor = parseInt(parts[1]);
if (parts.length > 2)
build = parseInt(parts[2]);
if (parts.length > 3)
revision = parseInt(parts[3]);
}
Major = major;
Minor = minor;
Build = build;
Revision = revision;
}
private static int parseInt(String str)
{
try
{
return Integer.parseInt(str);
}
catch (NumberFormatException e)
{
return 0;
}
}
#Override
public String toString()
{
return String.format("%s.%s.%s.%s", Major, Minor, Build, Revision);
}
public boolean isEmpty()
{
return (Major == 0 && Minor == 0 && Build == 0 && Revision == 0);
}
#Override
public int compareTo(Version another)
{
if (another == null)
throw new NullPointerException();
int[] thisV = new int[] { Major, Minor, Build, Revision };
int[] otherV = new int[] { another.Major, another.Minor, another.Build, another.Revision };
for (int i = 0; i < thisV.length; i++)
{
if (thisV[i] < otherV[i])
return -1;
else if (thisV[i] > otherV[i])
return +1;
// else, loop to consider less significant parts.
}
return 0; // All equal.
}
}
Related
Is there any equivalent to String.strip() in android, except trim()?
My development environments are Java11, minSdk24, targetSdk31 and compileSdk31. Is that possible to make String.strip() available if I upgrade one of them?
You can try upgrading your project to use Java 11, which has the function. Or write it yourself, its trivial.
public static String strip(String value) {
int firstChar = 0;
while (firstChar < value.length() && Character.isWhitespace(value.charAt(firstChar))) {
firstChar++;
}
int lastChar = value.length() - 1;
while (lastChar > firstChar && Character.isWhitespace(value.charAt(lastChar))) {
lastChar--;
}
return value.substring(firstChar, lastChar + 1);
}
Suppose we can use getPackageInfo in Package Manager in android and get any installed app's versionCode and all.
So can we find the architecture or the app? Like it's arm-v7a or arm64
I'll be very helpful to you.
Thank you
I found your question for "Java custom string encryption from a paragraph or set of strings", and would like to help because I've done something similar in c#.
I noticed that one of the largest reasons for that question being closed is because you were lacking in certain details that would help us determine what you needed.
This is an example of mine:
public static string Trans(string data) {
data = ToBinary(ConvertToByteArray(data));
string[] Adata = data.Split();
string output = "";
foreach(string word in Adata) {
int count = 0;
bool counting1s = false;
count = 0;
output = "";
foreach(var ch in word) {
if (ch == '0' && counting1s) {
counting1s = false;
if (count > 0) {
output += bit1[count - 1];
count = 0;
}
}
if (ch == '1' && !counting1s) {
counting1s = true;
if (count > 0) {
output += bit0[count - 1];
count = 0;
}
}
count++;
}
if (count > 0) {
output += (counting1s ? bit1 : bit0)[count - 1];
}
}
return output;
}
I could help you with making something in Java if youd like.
I am getting an error, while calculating on String,
java.lang.StringIndexOutOfBoundsException: length=4; regionStart=5; regionLength=2
My implementation is below.
private void initializeMyPLsAllotted() {
int theMonthWhenICame = Integer.parseInt(myDateHired.substring(5, 7)); //This line is showing the error
int theYearWhenICame = Integer.parseInt(myDateHired.substring(0,4));
int theCurrentMonth = Integer.parseInt(todaysDate.substring(5, 7));
int theCurrentYear = Integer.parseInt(todaysDate.substring(0, 4));
int myTotalMonths = (theCurrentYear - theYearWhenICame)*12 + theCurrentMonth - theMonthWhenICame;
if (myTotalMonths > 6) {
numberOfPLsAllotted = 2;
} else {
numberOfPLsAllotted = 0;
}
myPLs = numberOfPLsAllotted;
}
java.lang.StringIndexOutOfBoundsException: length=4; regionStart=5; regionLength=2
it clearly says that length of your string is 4 and you are trying to fetch sub-string from index 5. make sure your string is valid
you can check something like that to avoid crashing your app
private void initializeMyPLsAllotted() {
if(myDateHired.length() > 7 && todaysDate.length() > 7){
int theMonthWhenICame = Integer.parseInt(myDateHired.substring(5, 7));
int theYearWhenICame = Integer.parseInt(myDateHired.substring(0,4));
int theCurrentMonth = Integer.parseInt(todaysDate.substring(5, 7));
int theCurrentYear = Integer.parseInt(todaysDate.substring(0, 4));
int myTotalMonths = (theCurrentYear - theYearWhenICame)*12 + theCurrentMonth - theMonthWhenICame;
if(myTotalMonths>6) {
numberOfPLsAllotted = 2;
} else {
numberOfPLsAllotted = 0;
}
myPLs = numberOfPLsAllotted;
} else {
// print some error message
}
}
StringIndexOutOfBoundsException means that the section you're trying to substring is outside of the string length.
Example
String test = "123";
String testSubstringOne = test.substring(0, 1);
//testSubstringOne -> "1"
String testSubstringTwo = test.substring(0, 5);
//testSubstringTwo -> java.lang.StringIndexOutOfBoundsException
Make sure your myDateHired has the value you expect.
Tip from the coach
You say that those values are from a server... Maybe you should look into returning data in a more friendly format such as json.
As doc says, the IndexOutOfBoundsException will be throwed when:
if the beginIndex is negative, or endIndex is larger than the length
of this String object, or beginIndex is larger than endIndex
so check myDateHired before using it.
I've used Google Translate to translate the following string "I think CompanyXYZ is a great company in 2014 and beyond" to Hebrew and this resulted in
When I display this text in a TextView on a Galaxy S3 (Android 4.3), I get
which seems to be correct.
When I run the same program on a Galaxy Tab 7 (running Android 2.2), I get
which is obviously not correct.
Can I use android.support.v4.text.BidiFormatter and/or java.text.Bidi to render this correct?
When running the following code
Bidi bidi = new Bidi(text, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
for (int i = 0; i < bidi.getRunCount(); i++)
{
int start = bidi.getRunStart(i);
int level = bidi.getRunLevel(i);
int limit = bidi.getRunLimit(i);
Log.d("RTL", "bidi.run["+i+"] = "+start+";"+level+";"+limit+";"+ text.substring(start, limit));
}
I do get the following 5 runs
bidi.run[0] = 0;1;9;אני חושב
bidi.run[1] = 9;2;19;CompanyXYZ
bidi.run[2] = 19;1;36; היא חברה גדולה ב
bidi.run[3] = 36;2;40;2014
bidi.run[4] = 40;1;46; ומעבר
Hence all the information seems to be available to render this string correct but I don't know how to proceed. Can I use BidiFormatter? Or should I override TextView.draw()?
Ok, I realize it's been a while...
I made a function for my app which gets bidirectional strings, depending on the main direction which I thought would be helpful.
public static String getBidiString(String input, int direction) {
boolean rtlContext;
int defaultBidiDirection;
if (direction == Bidi.DIRECTION_LEFT_TO_RIGHT) {
rtlContext = false;
defaultBidiDirection = Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
} else /* if (lang == Util.Lang.HE) */{
rtlContext = true;
defaultBidiDirection = Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
}
Bidi bidi = new Bidi(input,defaultBidiDirection);
if (!bidi.isMixed()) return input;
BidiFormatter bidiFormatter = BidiFormatter.getInstance(rtlContext);
StringBuilder bidiTestBuilder = new StringBuilder();
for (int i = 0; i < bidi.getRunCount(); i++)
{
int start = bidi.getRunStart(i);
int level = bidi.getRunLevel(i);
int limit = bidi.getRunLimit(i);
String run = input.substring(start, limit);
if (level != direction) {
run = bidiFormatter.unicodeWrap(run,!rtlContext) + " ";
}
bidiTestBuilder.append(run);
}
return bidiTestBuilder.toString();
}
the direction parameter should be either Bidi.DIRECTION_LEFT_TO_RIGHT or Bidi.DIRECTION_RIGHT_TO_LEFT depending on the default direction of the text.
I certainly am not claiming that I implemented this completely correctly, but this code works for my use cases.
Rendering on your 2.2 device is not incorrect. The difference is that the paragraph direction is LTR. It is very common to set paragraph orientation "by context", which means - according to the first bid I run. But it is legitimate to set the direction otherwise. For example, Windows textbox allows the end user switch this direction by pressing left ctrlshift or right ctrlshift (left or right shift, does not matter). Usually, alignment follows this direction.
Official support for RTL layout direction was introduced in 4.2. But even before, since 2011 (it seems to be 4.0.1), there has been a #hide method View.setLayoutDirection() credits to Du Shunpeng, who published his answer a year ago.
Unfortunately, 2.2 is even older, and this non-public API was not available. Consider using WebView, it does support dir=rtl for div and text input.
Note that even back then, the ME versions of Android, including the Tab 7 device, were often customized by the manufacturer or distributor to provide some level of BiDi support, so it's important to test on the device that will be used by your audience.
I think below code can help you
public static Spannable getRtlBidiString(String input)
{
return getBidiString(Spannable.Factory.getInstance().newSpannable(input), Bidi.DIRECTION_RIGHT_TO_LEFT);
}
public static Spannable getForceRtlBidiString(String input)
{
return getForceBidiString(Spannable.Factory.getInstance().newSpannable(input), Bidi.DIRECTION_RIGHT_TO_LEFT);
}
public static Spannable getRtlBidiString(Spannable input)
{
return getBidiString(input, Bidi.DIRECTION_RIGHT_TO_LEFT);
}
public static Spannable getLtrBidiString(Spannable input)
{
return getBidiString(input, Bidi.DIRECTION_LEFT_TO_RIGHT);
}
public static Spannable getLtrBidiString(String input)
{
return getBidiString(Spannable.Factory.getInstance().newSpannable(input), Bidi.DIRECTION_LEFT_TO_RIGHT);
}
public static Spannable getBidiString(Spannable input, int direction)
{
boolean isRtl;
int baseDirection;
TextDirectionHeuristicCompat heu;
if (direction == Bidi.DIRECTION_LEFT_TO_RIGHT)
{
isRtl = false;
baseDirection = Bidi.DIRECTION_LEFT_TO_RIGHT;
heu = TextDirectionHeuristicsCompat.FIRSTSTRONG_LTR;
}
else /* if (lang == Util.Lang.HE) */
{
isRtl = true;
baseDirection = Bidi.DIRECTION_RIGHT_TO_LEFT;
heu = TextDirectionHeuristicsCompat.FIRSTSTRONG_RTL;
}
Bidi bidi = new Bidi(input.toString(), baseDirection);
if (!bidi.isMixed())
return input;
BidiFormatter bidiFormatter = BidiFormatter.getInstance(isRtl);
SpannableStringBuilder bidiBuilder = new SpannableStringBuilder();
for (int i = 0; i < bidi.getRunCount(); i++)
{
int start = bidi.getRunStart(i);
int level = bidi.getRunLevel(i);
int limit = bidi.getRunLimit(i);
CharSequence run = input.subSequence(start, limit);
if (level != baseDirection)
{
run = bidiFormatter.unicodeWrap(run, heu, !isRtl).toString();
}
bidiBuilder.append(run);
}
return bidiBuilder;
}
public static Spannable getForceBidiString(Spannable input, int direction)
{
boolean isRtl;
int baseDirection;
TextDirectionHeuristicCompat heu;
if (direction == Bidi.DIRECTION_LEFT_TO_RIGHT)
{
isRtl = false;
baseDirection = Bidi.DIRECTION_LEFT_TO_RIGHT;
heu = TextDirectionHeuristicsCompat.ANYRTL_LTR;
}
else /* if (lang == Util.Lang.HE) */
{
isRtl = true;
baseDirection = Bidi.DIRECTION_RIGHT_TO_LEFT;
heu = TextDirectionHeuristicsCompat.ANYRTL_LTR;
}
Bidi bidi = new Bidi(input.toString(), baseDirection);
if (!bidi.isMixed())
return input;
BidiFormatter bidiFormatter = BidiFormatter.getInstance(isRtl);
SpannableStringBuilder bidiBuilder = new SpannableStringBuilder();
for (int i = 0; i < bidi.getRunCount(); i++)
{
int start = bidi.getRunStart(i);
int level = bidi.getRunLevel(i);
int limit = bidi.getRunLimit(i);
CharSequence run = input.subSequence(start, limit);
if (level != baseDirection)
{
run = bidiFormatter.unicodeWrap(run, heu, !isRtl).toString();
}
bidiBuilder.append(run);
}
return bidiBuilder;
}
On Android-Wheel project at http://code.google.com/p/android-wheel/
Blog at http://android-devblog.blogspot.com/2011/01/android-wheel-update-custom-views-for.html
What/where should be changed so minutes (as example) on the time wheel, would show only numbers 00, 15, 30, 45 rather than all numbers 00 to 59 ?
The author, Kankan said: "just use a custom adapter based on the numeric one, with predefined items." But this is not enough lead to help me to change the project/code.
Can you provide specific lead on What/Where in the project should be changed ?
I just thought if this helps someone they can try this approach. I created a sample class
public class NumericWheelAdapterV2 extends AbstractWheelTextAdapter {
protected NumericWheelAdapterV2(Context context) {
super(context);
}
#Override
public int getItemsCount() {
return 4;
}
#Override
protected CharSequence getItemText(int index) {
if(0 == index){
return "00";
}else if(1 == index){
return "15";
} else if (2 == index){
return "30";
}else if (3 == index){
return "45";
}
return null;
}
}
If you check out the project and poke around a bit you'll find "NumericWheelAdapter" to be a good starting point to look into.
The example does
#Override
public CharSequence getItemText(int index) {
if (index >= 0 && index < getItemsCount()) {
int value = minValue + index;
return format != null ? String.format(format, value) : Integer.toString(value);
}
return null;
}
You could create your own NumericWheelAdapter that overrides CharSequence and instead of generating a value for each index, you can do something like index x 15 to get 0, 15, 30 ,45 and set min and max to 0 and 3.
I think you should be able to modify the code to your liking with these indications, otherwise if after trial and error you can't, you can always come back for more help ^^
Cheers
Jason