我为我的应用编写了一个 AppWidget,你可以选择一个你喜欢的地方的名称,它会向你显示来自那个地方的照片。
它有一个配置 Activity(我使用了与应用程序本身相同的配置 Activity) 首次添加时,小部件及其配置处理工作正常:我选择了一个我喜欢的地方,然后我看到了图片;
问题是每当我重新启动设备(或者它退出 sleep 模式) 然后当我点击它(小部件)时,我进入配置 Activity - 更改为所需的图片但没有任何反应 当我调试时,我可以看到:
appWidgetManager.updateAppWidget(mAppWidgetId, views);
mAppWidgetId =
有一个 id,并且 views 不是 null。
那么黑客是怎么回事?
我的想法是,在设备重新启动时,widgetId 会发生变化,并且我不会像我应该的那样处理它。
顺便说一句,如果在模拟器上尝试相同的操作,我没有问题,一切正常
这是我的代码:
list .xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.dryrun" android:versionCode="3"
android:versionName="1.1" android:installLocation="auto">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/ic_launcher_test"
android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:debuggable="true"><!-- different< android:theme="@style/Theme.NoBackground" -->
<!-- Main Activity -->
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Preferences -->
<activity android:name=".Preferences.EditPreferences">
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</activity>
<!-- Widgets -->
<!-- Widget-->
<receiver android:name=".Widget.testWidget" android:label="@string/app_widget_">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<!--action
android:name="com.test.dryrun.Widget.testWidget.PREFENCES_WIDGET_CONFIGURE" /-->
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/test_widget__provider" />
</receiver>
<service android:name=".Widget.testWidget$WidgetService" />
<uses-permission android:name="android.permission.BIND_REMOTEVIEWS"></uses-permission>
</application>
</manifest>
appwidget_provider xml
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="146dip"
android:updatePeriodMillis="0"
android:initialLayout="@layout/test_widget"
/>
小部件类
public class testWidget extends AppWidgetProvider {
public static String PREFENCES_WIDGET_CONFIGURE = "ActionConfigureWidget";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Intent svcIntent = new Intent(context, WidgetService.class);
widgets = appWidgetIds;
context.startService(svcIntent);
}
@Override
public void onReceive(Context context, Intent intent)
{
// v1.5 fix that doesn't call onDelete Action
final String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action))
{
final int appWidgetId = intent.getExtras().getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID)
{
this.onDeleted(context, new int[] { appWidgetId });
}
}
else
{
super.onReceive(context, intent);
}
}
//public void updateWidget()
/**
* @param context
* @param remoteViews
*/
public static void updateWidget(Context context, RemoteViews remoteViews)
{
String Prefix = context.getString(R.string._prefix);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String ToShow = prefs.getString(context.getString(
R.string.Widget_string),
context.getString(R.string.default_string));
String pkgName = context.getPackageName();
int resID = context.getResources().getIdentifier(Prefix + ToShow, "drawable", pkgName);
WidgetController widgetController = WidgetController.getInstance();
widgetController.setRemoteViewImageViewSource(remoteViews, R.id.WidgetImage, resID);
}
public static class WidgetService extends Service
{
@Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
// Update the widget
RemoteViews remoteView = buildRemoteView(this);
// Push update to homescreen
WidgetController.getInstance().pushUpdate(
remoteView,
getApplicationContext(),
testWidget.class);
// No more updates so stop the service and free resources
stopSelf();
}
public RemoteViews buildRemoteView(Context context)
{
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.test_widget);
Intent configIntent = new Intent(context, EditPreferences.class);
configIntent.setAction(testWidget.PREFENCES_WIDGET_CONFIGURE);
configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgets[0]);
//configIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent runtestPendingIntent = PendingIntent.getActivity(context, 0, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.WidgetImage, runtestPendingIntent);
WidgetController controller = WidgetController.getInstance();
controller.updateWidget(context, remoteViews);
return remoteViews;
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
int oldOrientation = this.getResources().getConfiguration().orientation;
if(newConfig.orientation != oldOrientation)
{
// Update the widget
RemoteViews remoteView = buildRemoteView(this);
// Push update to homescreen
WidgetController.getInstance().pushUpdate(
remoteView,
getApplicationContext(),
testWidget.class);
}
}
@Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
}
}
偏好类
public class EditPreferences extends PreferenceActivity implements OnSharedPreferenceChangeListener
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
Intent intent = getIntent();
m_extras = intent.getExtras();
}
private Bundle m_extras;
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
if(key.equals(getString(R.string.rlvntString)))
{
Context ctx = getApplicationContext();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(ctx);
setResult(RESULT_CANCELED);
if (m_extras != null)
{
Intent resultValue = new Intent();
String stringID = AppWidgetManager.EXTRA_APPWIDGET_ID;
mAppWidgetId = m_extras.getInt(
stringID,
AppWidgetManager.INVALID_APPWIDGET_ID);
RemoteViews views = new RemoteViews(ctx.getPackageName(),R.layout.test_widget);
WidgetController.getInstance().updateWidget(ctx, views);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
resultValue.putExtra(stringID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
}
}
}
最佳答案
为了将来的需要。我在我的小部件的布局 xml 中添加了一个按钮。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical" >
<TextView
android:id="@+id/timeout_title"
android:layout_width="match_parent"
android:layout_height="40dp"
android:textStyle="bold"
android:gravity="center"/>
<!-- ListView to be shown on widget -->
<ListView
android:id="@+id/timeoutListViewWidget"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_marginEnd="45dp"
android:divider="@null"
/>
<ImageButton
android:id="@+id/timeout_edit"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:src="@drawable/pen"
/>
<!-- Empty view is show if list items are empty -->
<TextView
android:id="@+id/timeOutEmpty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Veri Listesi boş"
android:textColor="#ffffff"
android:textSize="20sp"
android:visibility="gone" />
</LinearLayout>
然后我在我的 widgetproviders 类中定义了 remoteviews 的地方定义了 onClick 监听器;
private RemoteViews updateWidgetListView(Context context,
int appWidgetId) {
//which layout to show on widget
RemoteViews remoteViews = new RemoteViews(
context.getPackageName(), R.layout.timeout_widget);
Intent svcIntent = new Intent(context, TimeoutWidgetService.class);
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
svcIntent.setData(Uri.parse(
svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
remoteViews.setRemoteAdapter( R.id.timeoutListViewWidget, svcIntent);
remoteViews.setEmptyView(R.id.timeOutEmpty_view, R.id.timeOutEmpty_view);
Intent configIntent = new Intent(context, AppWidgetDepLevelActivity.class);
configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// Make this unique for this appWidgetId
configIntent.setData(Uri.withAppendedPath(Uri.parse("customuri://widget/id/"), String.valueOf(appWidgetId)));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, configIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.timeout_edit, pendingIntent);
return remoteViews;
}
然后在我的 ConfigurationActivity 中我创建了包含我的配置更改的新包;
Bundle newOps = new Bundle();
newOps.putInt("level",0);
并调用了;
appWidgetManager.updateAppWidgetOptions(appWidgetId,newOps);
整个函数;
private void updateAppWidgetOptions() {
appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
appWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
RemoteViews views = new RemoteViews(getApplicationContext().getPackageName(),
R.layout.timeout_widget);
Bundle newOps = new Bundle();
newOps.putInt("level",0);
appWidgetManager.updateAppWidgetOptions(appWidgetId,newOps);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
}
并且此函数触发了我的 appwidget 提供程序类中覆盖的 onAppWidgetOptionsChanged 函数,我在那里运行我的逻辑。
这是函数;
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
Log.d("APPWIGET","onAppWidgetOptionsChanged");
Object level = newOptions.get("level");
if(level!= null){
Log.d("APPWIGET",level.toString());
}
Date date = new Date();
now = date.getTime();
this.appWidgetId = appWidgetId;
this.appWidgetManager = appWidgetManager;
getTimeOutReportData(context);
}
关于java - 配置更改后小部件不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7766779/
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht