getRelativeTimeSpanString的默认语言环境

我重写我的应用程序的区域使用:

Locale locale = new Locale("ca"); Locale.setDefault(locale); Configuration config = new Configuration(); config.locale = locale; getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics()); 

但似乎getRelativeTimeSpanString不适用于应用程序上下文,而是使用系统区域设置。

Solutions Collecting From Web of "getRelativeTimeSpanString的默认语言环境"

你的解决scheme几乎是正确的

但是,由于string是从系统资源加载的,因此必须更新系统资源的configuration。 以下是我所做的:

  Configuration configuration = new Configuration(Resources.getSystem().getConfiguration()); configuration.locale = Locale.GERMANY; // or whichever locale you desire Resources.getSystem().updateConfiguration(configuration, null); 

(注意:从果冻豆MR1起,build议使用

 configuration.setLocale(Locale.GERMANY); 

改变语言环境而不是直接设置成员。)

我今天有这个问题,花了我几个小时来“解决”。

我build议你,如果你可以使用getRelativeTimeSpanString(context,long,boolean)来代替。 这不是我的情况,因为结果string不是getRelativeTimeSpanString(长)。

我的解决方法需要将一些string的一些android内部资源复制到你的代码中,所以如果你有很多语言需要支持的话,这将是相当麻烦的。

我跟踪了Android(4.4 r1)的当前源代码并提取了DateUtils并进行了更改,以便您可以像这样使用它:

 CharSequence desiredString = MyDateUtils.getRelativeTimeSpanString(time, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR, activity); 

这会给你getRelativeTimeSpanString(长)相同的结果。

为了使MyDateUtils我只保留:

public static CharSequence getRelativeTimeSpanString(long time,long now,long minResolution,int flags,Context c)

我添加了上下文的方法,然后改变了上下文资源的系统资源和我自己的string的所有内部的Androidstring(这是相同的android的,但没有find一种方式来使用它们,因为它们是内部的 )。

private static final String getRelativeDayString(Resources r,long day,long today)

也保留了以前使用的这种方法。 在这里,我也改变了string。

用于复制粘贴目的

这是我的MyDateUtils的实现:

 import java.util.Locale; import android.content.Context; import android.content.res.Resources; import android.text.format.DateUtils; import android.text.format.Time; import com.YOURPACKAGE.R; /** * This class contains various date-related utilities for creating text for things like * elapsed time and date ranges, strings for days of the week and months, and AM/PM text etc. */ public class MyDateUtils { /** * Returns a string describing 'time' as a time relative to 'now'. * <p> * Time spans in the past are formatted like "42 minutes ago". Time spans in * the future are formatted like "in 42 minutes". * <p> * Can use {@link #FORMAT_ABBREV_RELATIVE} flag to use abbreviated relative * times, like "42 mins ago". * * @param time the time to describe, in milliseconds * @param now the current time in milliseconds * @param minResolution the minimum timespan to report. For example, a time * 3 seconds in the past will be reported as "0 minutes ago" if * this is set to MINUTE_IN_MILLIS. Pass one of 0, * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, * WEEK_IN_MILLIS * @param flags a bit mask of formatting options, such as * {@link #FORMAT_NUMERIC_DATE} or * {@link #FORMAT_ABBREV_RELATIVE} */ public static CharSequence getRelativeTimeSpanString(long time, long now, long minResolution, int flags, Context c) { Resources r = c.getResources(); //boolean abbrevRelative = (flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0; boolean past = (now >= time); long duration = Math.abs(now - time); int resId; long count; if (duration < DateUtils.MINUTE_IN_MILLIS && minResolution < DateUtils.MINUTE_IN_MILLIS) { count = duration / DateUtils.SECOND_IN_MILLIS; if (past) { resId = R.plurals.num_seconds_ago; } else { resId = R.plurals.in_num_seconds; } } else if (duration < DateUtils.HOUR_IN_MILLIS && minResolution < DateUtils.HOUR_IN_MILLIS) { count = duration / DateUtils.MINUTE_IN_MILLIS; if (past) { resId = R.plurals.num_minutes_ago; } else { resId = R.plurals.in_num_minutes; } } else if (duration < DateUtils.DAY_IN_MILLIS && minResolution < DateUtils.DAY_IN_MILLIS) { count = duration / DateUtils.HOUR_IN_MILLIS; if (past) { resId = R.plurals.num_hours_ago; } else { resId = R.plurals.in_num_hours; } } else if (duration < DateUtils.WEEK_IN_MILLIS && minResolution < DateUtils.WEEK_IN_MILLIS) { return getRelativeDayString(r, time, now); } else { // We know that we won't be showing the time, so it is safe to pass // in a null context. return DateUtils.formatDateRange(null, time, time, flags); } String format = r.getQuantityString(resId, (int) count); return String.format(format, count); } /** * Returns a string describing a day relative to the current day. For example if the day is * today this function returns "Today", if the day was a week ago it returns "7 days ago", and * if the day is in 2 weeks it returns "in 14 days". * * @param r the resources * @param day the relative day to describe in UTC milliseconds * @param today the current time in UTC milliseconds */ private static final String getRelativeDayString(Resources r, long day, long today) { Locale locale = r.getConfiguration().locale; if (locale == null) { locale = Locale.getDefault(); } // TODO: use TimeZone.getOffset instead. Time startTime = new Time(); startTime.set(day); int startDay = Time.getJulianDay(day, startTime.gmtoff); Time currentTime = new Time(); currentTime.set(today); int currentDay = Time.getJulianDay(today, currentTime.gmtoff); int days = Math.abs(currentDay - startDay); boolean past = (today > day); // TODO: some locales name other days too, such as de_DE's "Vorgestern" (today - 2). if (days == 1) { if (past) { return r.getString(R.string.yesterday); } else { return r.getString(R.string.tomorrow); } } else if (days == 0) { return r.getString(R.string.today); } int resId; if (past) { resId = R.plurals.num_days_ago; } else { resId = R.plurals.in_num_days; } String format = r.getQuantityString(resId, days); return String.format(format, days); } } 

在值文件夹string.xml中添加:

 <?xml version="1.0" encoding="utf-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="yesterday">yesterday</string> <string name="tomorrow">tomorrow</string> <string name="today">today</string> <plurals name="num_seconds_ago"> <item quantity="one">1 second ago</item> <item quantity="other"><xliff:g id="count">%d</xliff:g> seconds ago</item> </plurals> <plurals name="num_minutes_ago"> <item quantity="one">1 minute ago</item> <item quantity="other"><xliff:g id="count">%d</xliff:g> minutes ago</item> </plurals> <plurals name="num_hours_ago"> <item quantity="one">1 hour ago</item> <item quantity="other"><xliff:g id="count">%d</xliff:g> hours ago</item> </plurals> <plurals name="num_days_ago"> <item quantity="one">yesterday</item> <item quantity="other"><xliff:g id="count">%d</xliff:g> days ago</item> </plurals> <plurals name="in_num_seconds"> <item quantity="one">in 1 second</item> <item quantity="other">in <xliff:g id="count">%d</xliff:g> seconds</item> </plurals> <plurals name="in_num_minutes"> <item quantity="one">in 1 minute</item> <item quantity="other">in <xliff:g id="count">%d</xliff:g> minutes</item> </plurals> <plurals name="in_num_hours"> <item quantity="one">in 1 hour</item> <item quantity="other">in <xliff:g id="count">%d</xliff:g> hours</item> </plurals> <plurals name="in_num_days"> <item quantity="one">tomorrow</item> <item quantity="other">in <xliff:g id="count">%d</xliff:g> days</item> </plurals> </resources> 

作为一个例子,对于另一种语言,如葡萄牙语,在values-pt文件夹string.xml中:

 <?xml version="1.0" encoding="utf-8"?> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="yesterday">ontem</string> <string name="tomorrow">manhã</string> <string name="today">hoje</string> <plurals name="num_seconds_ago"> <item msgid="4869870056547896011" quantity="one">"1 segundo atrás"</item> <item msgid="3903706804349556379" quantity="other">"<xliff:g id="COUNT">%d</xliff:g> segundos atrás"</item> </plurals> <plurals name="num_minutes_ago"> <item msgid="3306787433088810191" quantity="one">"1 minuto atrás"</item> <item msgid="2176942008915455116" quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minutos atrás"</item> </plurals> <plurals name="num_hours_ago"> <item msgid="9150797944610821849" quantity="one">"1 hora atrás"</item> <item msgid="2467273239587587569" quantity="other">"<xliff:g id="COUNT">%d</xliff:g> horas atrás"</item> </plurals> <plurals name="num_days_ago"> <item msgid="861358534398115820" quantity="one">"ontem"</item> <item msgid="2479586466153314633" quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dias atrás"</item> </plurals> <plurals name="in_num_seconds"> <item msgid="2729745560954905102" quantity="one">"em 1 segundo"</item> <item msgid="1241926116443974687" quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> segundos"</item> </plurals> <plurals name="in_num_minutes"> <item msgid="8793095251325200395" quantity="one">"em 1 minuto"</item> <item msgid="3330713936399448749" quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> minutos"</item> </plurals> <plurals name="in_num_hours"> <item msgid="7164353342477769999" quantity="one">"em 1 hora"</item> <item msgid="547290677353727389" quantity="other">"Em <xliff:g id="COUNT">%d</xliff:g> horas"</item> </plurals> <plurals name="in_num_days"> <item msgid="5413088743009839518" quantity="one">"amanhã"</item> <item msgid="5109449375100953247" quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> dias"</item> </plurals> </resources> 

我使用Custom方法来处理这个问题:

 public static String getRelativeTimeSpanString(Context context, Date fromdate) { long then; then = fromdate.getTime(); Date date = new Date(then); StringBuffer dateStr = new StringBuffer(); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); Calendar now = Calendar.getInstance(); int days = daysBetween(calendar.getTime(), now.getTime()); int weeks= days/7; int minutes = hoursBetween(calendar.getTime(), now.getTime()); int hours = minutes / 60; if (days == 0) { int second = minuteBetween(calendar.getTime(), now.getTime()); if (minutes > 60) { if (hours >= 1 && hours <= 24) { dateStr.append(String.format("%s %s %s", hours, context.getString(R.string.hour) ,context.getString(R.string.ago))); } }else { if (second <= 10) { dateStr.append(context.getString(R.string.now)); } else if (second > 10 && second <= 30) { dateStr.append(context.getString(R.string.few_seconds_ago)); } else if (second > 30 && second <= 60) { dateStr.append(String.format("%s %s %s", second, context.getString(R.string.seconds) ,context.getString(R.string.ago))); } else if (second >= 60 && minutes <= 60) { dateStr.append(String.format("%s %s %s", minutes, context.getString(R.string.minutes) ,context.getString(R.string.ago))); } } } else if (hours > 24 && days < 7) { dateStr.append(String.format("%s %s %s", days, context.getString(R.string.days) ,context.getString(R.string.ago))); }else if(weeks == 1){ dateStr.append(String.format("%s %s %s", weeks, context.getString(R.string.weeks) ,context.getString(R.string.ago))); } else { /** * make formatted createTime by languageTag("fa") * * @return */ return SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG,new Locale("fra")) .format(date).toUpperCase(); } return dateStr.toString(); } public static int minuteBetween(Date d1, Date d2) { return (int) ((d2.getTime() - d1.getTime()) / android.text.format.DateUtils.SECOND_IN_MILLIS); } public static int hoursBetween(Date d1, Date d2) { return (int) ((d2.getTime() - d1.getTime()) / android.text.format.DateUtils.MINUTE_IN_MILLIS); } public static int daysBetween(Date d1, Date d2) { return (int) ((d2.getTime() - d1.getTime()) / android.text.format.DateUtils.DAY_IN_MILLIS); } 

我把date设置为这个方法的一个参数:

  return getRelativeTimeSpanString(context,this.createdTime); 

这个返回string的位置,因为我想要的! 希望有所帮助。