get the string resources dynamic for a question app - android

I am developing a question app. I got some questions in my string resource file. Each time a user touches the textview it changes the question.
I have all the questions stored in an array, but I don't think this is very efficient.
max_Fragen = FragenBeginner.length - 1;
min_Fragen = 0;
//Fragen Nummer
randomFrage = rand.nextInt((max_Fragen - min_Fragen) + 1) + min_Fragen;
fragekatalog = getResources().getString(R.string.fragen_FragenBeginner_ + randomFrage);
frage.setText(fragekatalog);

You can use
public static int getStringIdentifier(Context context, String name) {
return context.getResources().getIdentifier(name, "string", context.getPackageName());
}
to use a variable as a string identifier.

Related

Android - getResources().getIdentifier replacement

In android I am looping through the database and assigning text and image:
Cursor res = myDb.getAllData();
while (res.moveToNext()) {
Actors actor = new Actors();
actor.setName(res.getString(1));
String th = res.getString(11);
Integer thumb = this.getResources().getIdentifier(th, "drawable", "mypackage");
actor.setThumb(R.drawable.th);
}
However Lint suggests not to use getIdentifier - Use of this function is discouraged because resource reflection makes it harder to perform build optimizations and compile-time verification of code.
In database column I have just the image name (string). How can I replace getIdentifier?
Even if I change the DB column maybe directly to R.drawable.imagename, it is still a string and for setThumb I need a drawable.
Ok, so the only solution what I've found is here https://stackoverflow.com/a/4428288/1345089
public static int getResId(String resName, Class<?> c) {
try {
Field idField = c.getDeclaredField(resName);
return idField.getInt(idField);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
and then just calling:
int resID = getResId("icon", R.drawable.class);
This works very well, however some users reports, that after installing the app from Play store (not my app, but any with this method implemented and proguard enabled), after a while it will start throwing NoSuchFieldException, as more resources are mapped to the same class/field.
It can be caused by proguard but not sure. The solution is then to put the old way getResources().getIdentifier to the exception part of code.
You can try this approach:
Rename your resources as follow:
ressourceName00
ressourceName01
ressourceName02 .... and so on,
then use the methode below:
for (int i = 0; i < RessourceQtt; i++) {
Uri path1 = Uri.parse("android.resource://yourPackage Directories/drawable/ressourceName0" + i);
list.add(new CarouselItem(String.valueOf(path1)));
}
You can try this my code three way
// Show message and quit
Application app = cordova.getActivity().getApplication();
String package_name = app.getPackageName();
Resources resources = app.getResources();
String message = resources.getString(resources.getIdentifier("message", "string", package_name));
String label = resources.getString(resources.getIdentifier("label", "string", package_name));
this.alert(message, label);
set icon like that
private int getIconResId() {
Context context = getApplicationContext();
Resources res = context.getResources();
String pkgName = context.getPackageName();
int resId;
resId = res.getIdentifier("icon", "drawable", pkgName);
return resId;
}
this is also
//set icon image
final String prefix = "ic_";
String icon_id = prefix + cursor.getString(cursor.getColumnIndex(WeatherEntry.COLUMN_ICON));
Resources res = mContext.getResources();
int resourceId = res.getIdentifier(icon_id, "drawable", mContext.getPackageName());
viewHolder.imgIcon.setImageResource(resourceId);
I hope this code help for you.
public static int getIcId(String resN, Class<?> c) {
try {
Field idF = c.getDeclaredField(resN);
return idF.getInt(idF);
} catch (Exception e) {
throw new RuntimeException("No resource ID found for: "
+ resN+ " / " + c, e);
}}

How to delete the last occurrence of a function name (e.g. "cos" or "ln" or "tan") in a calculator edittext with one click?

I wanted to delete the last occurrence of a function name in a calculator edittext with one click.
I already have a delete button, which looks like this:
private void onDelete() {
final Editable formulaText = mFormulaEditText.getEditableText();
final int formulaLength = formulaText.length();
if (formulaLength > 0) {
formulaText.delete(formulaLength - 1, formulaLength);
}
}
I tried to get the last 3 character than if it equals with the function name, delete 3 letters, but the problem is that there are some longer (e.g.: atanh) or shorter function names (e.g.: ln).
P. S. Sorry for my English.
You could use a regular expression:
private static String removeLastMathFunction(String input) {
final String mathFnRegex = "(ln|log|a?(sin|cos|tan)h?)";
final String lastMathFnRegex = mathFnRegex + "(?!.*" + mathFnRegex + ")";
return input.replaceAll(lastMathFnRegex, "");
}
private void onDelete() {
String oldInputValue = mFormulaEditText.getText().toString();
String newInputValue = removeLastMathFunction(oldInputValue);
mFormulaEditText.setText(newInputValue);
}

Is it a good thing to write logic based on the hex value of id generated in R.java android

This what I have seen in an android application. They have a number of image buttons with ids
R.java :
public static final int img1=0x7f090080;
public static final int img2=0x7f090081;
public static final int img3=0x7f090082;
public static final int img4=0x7f090083;
public static final int img5=0x7f090084;
public static final int img6=0x7f090085;
public static final int img7=0x7f090086;
public static final int img8=0x7f090087;
In one of the activity they are traversing a for loop like below:
for (int i = 0; i < NoOfButtons; i++) {
if (i == pos) {
((ImageView) vi.findViewById(R.id.img1 + i)).setImageResource(R.drawable.circular_pagination_red);
} else {
((ImageView) vi.findViewById(R.id.img1 + i)).setImageResource(R.drawable.circular_pagination_brown);
}
I want to know how much safe and advisable it is.
One thing this is working absolutely fine. I been a part of this from months and never seen a problem in this logic. But still it irks me a bit.
Note : I am not getting any error and I know the alternate solution also. My only concern is if it is not advisable/safe I want to know why? Another is scenarios where it can create havoc for me. I have a good understanding about R.java.
Though this might work OK most of the times, this is definitely not advisable. The R class is generated automatically thus you have no control over it and it could change. There is a solution to this problem using a typed array in resources. Check for example this answer.
You might want to use reflection.
Add this method to your code:
protected final static int getResourceID
(final String resName, final String resType, final Context ctx)
{
final int ResourceID =
ctx.getResources().getIdentifier(resName, resType,
ctx.getApplicationInfo().packageName);
if (ResourceID == 0)
{
throw new IllegalArgumentException
(
"No resource string found with name " + resName
);
}
else
{
return ResourceID;
}
}
And use it like this:
int myID =
getResourceID("your_resource_name", "drawable", getApplicationContext());
Note: no path (and no extension, in case of images).

Android: Convert first letter of string to lower case

I'm looking for a way to convert the first letter of a string to a lower case letter. The code I'm using pulls a random String from an array, displays the string in a text view, and then uses it to display an image. All of the strings in the array have their first letter capitalized but image files stored in the app cannot have capital letters, of course.
String source = "drawable/"
//monb is randomly selected from an array, not hardcoded as it is here
String monb = "Picture";
//I need code here that will take monb and convert it from "Picture" to "picture"
String uri = source + monb;
int imageResource = getResources().getIdentifier(uri, null, getPackageName());
ImageView imageView = (ImageView) findViewById(R.id.monpic);
Drawable image = getResources().getDrawable(imageResource);
imageView.setImageDrawable(image);
Thanks!
if (monb.length() <= 1) {
monb = monb.toLowerCase();
} else {
monb = monb.substring(0, 1).toLowerCase() + monb.substring(1);
}
public static String uncapitalize(String s) {
if (s!=null && s.length() > 0) {
return s.substring(0, 1).toLowerCase() + s.substring(1);
}
else
return s;
}
Google Guava is a java library with lot of utilities and reusable components. This requires the library guava-10.0.jar to be in classpath. The following example shows using various CaseFormat conversions.
import com.google.common.base.CaseFormat;
public class CaseFormatTest {
/**
* #param args
*/
public static void main(String[] args) {
String str = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, "studentName");
System.out.println(str); //STUDENT_NAME
str = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "STUDENT_NAME");
System.out.println(str); //studentName
str = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, "student-name");
System.out.println(str); //StudentName
str = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, "StudentName");
System.out.println(str); //student-name
}
}
Output Like:
STUDENT_NAME
studentName
StudentName
student-name

How to get the number of unread gmail mails (on android)

Please note there is a new way of doing this
I've been trying to get the number of unread gmail mails with no luck.
I've read Gmail.java and gmail4j both links taken out of this site from this question: Android - How can I find out how many unread email the user has?
But still after having read all of that and a couple of other sites that talked about this particular subject my question remains:
Q: How can I get the Gmail Unread Count?
Sorry if it seams a bit insistent but I clearly lack the knowledge to find this out on my own from the source.
PS: I would like to clarify that I want to do it without having to ask the user for credentials.
Just 2 add some colors to the question let me show you the looks of my app.
Please note there is a new way of doing this
Here's some code snippet. Not sure it works and can't test it. But I hope it will help you to continue the investigation.
public static final class LabelColumns {
public static final String CANONICAL_NAME = "canonicalName";
public static final String NAME = "name";
public static final String NUM_CONVERSATIONS = "numConversations";
public static final String NUM_UNREAD_CONVERSATIONS = "numUnreadConversations";
}
public void queryLabels(){
String account="email#company.com";
Uri LABELS_URI = Uri.parse("content://gmail-ls/labels/");
Uri ACCOUNT_URI = Uri.withAppendedPath(LABELS_URI, account);
ContentResolver contentResolver=myActivity.getContentResolver();
Cursor cursor = contentResolver.query(ACCOUNT_URI, null, null, null, null);
//iterate over all labels in the account
if (cursor.moveToFirst()) {
int unreadColumn = cursor.getColumnIndex(LabelColumns.NUM_UNREAD_CONVERSATIONS);
int nameColumn = cursor.getColumnIndex(LabelColumns.NAME);
do {
String name = cursor.getString(nameColumn);
String unread = cursor.getString(unreadColumn);//here's the value you need
} while (cursor.moveToNext());
}
}
Requires permission
<uses-permission android:name="com.google.android.gm.permission.READ_GMAIL"/>
This is how I've seen it done in a simple widget for the awesome window manager (yes, that's its name :)). Original script is here: gmail.lua.
The basic concept is to just use the inbox feed and get all the mails (you'll get just the summaries, not the whole content) for the special 'unread' tag. The URL is https://mail.google.com/mail/feed/atom/unread, you just have to fetch it (after authentication, of course), and then parse it. You can either use some sort of XML parser or just a simple regexp (<fullcount>([%d]+)</fullcount>) - the number you are looking for is at the beginning, in the <fullcount> tag.
So, that's one way of doing it, quite simple and "dumb", but hey, it works :D It might not be the best solution, as it requires you to fetch the whole feed (depending on the number of your unread messages and the type/quality of connection, it might not be as fast as just fetching the number of unread messages), but as usual, real-life testing should clear that up :)
There is new way how to do it. Old way doesn´t work anymore (21.01.2013).
Check following link:
Gmail Public Labels API
Maybe you can use the Gmail ContentProvider, please see http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/provider/Gmail.java&q=Gmail.java&sa=N&cd=1&ct=rc
There is a method getNumUnreadConversations or you could use a Observer.
static final String AUTHORITY = "com.google.android.gm";
static final String BASE_URI_STRING = "content://" + AUTHORITY;
static final String LABELS_PARAM = "/labels";
static final String ACCOUNT_TYPE_GOOGLE = "com.google";
public static final String NUM_UNREAD_CONVERSATIONS = "numUnreadConversations";
public static final String CANONICAL_NAME = "canonicalName";
public static final String CANONICAL_NAME_INBOX_CATEGORY_PRIMARY = "^sq_ig_i_personal";
static String[] GMAIL_PROJECTION = {
CANONICAL_NAME, NUM_UNREAD_CONVERSATIONS
};
public static Uri getLabelsUri(String account) {
return Uri.parse(BASE_URI_STRING + "/" + account + LABELS_PARAM);
}
static String[] getAllAccountNames(Context context) {
final Account[] accounts = AccountManager.get(context).getAccountsByType(
ACCOUNT_TYPE_GOOGLE);
final String[] accountNames = new String[accounts.length];
for (int i = 0; i < accounts.length; i++) {
accountNames[i] = accounts[i].name;
}
return accountNames;
}
protected static int getGmail(Context context) {
ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(Launcher.getLabelsUri(BadgeUtils.getAllAccountNames(context)[0]),
GMAIL_PROJECTION,
null, null,
null);
if (cursor == null || cursor.isAfterLast()) {
Log.d(TAG, "No Gmail inbox information found for account.");
if (cursor != null) {
cursor.close();
}
return 0;
}
int count = 0;
while (cursor.moveToNext()) {
if (CANONICAL_NAME_INBOX_CATEGORY_PRIMARY.equals(cursor.getString(cursor.getColumnIndex(CANONICAL_NAME)))) {
count = cursor.getInt(cursor.getColumnIndex(NUM_UNREAD_CONVERSATIONS));;
break;
}
}
cursor.close();
return count;
}
Hope above code helps. This should work on Android 2.2+.

Categories

Resources