【问题标题】:Android Widgets - Reset on screen Orientation changeAndroid 小部件 - 重置屏幕方向更改
【发布时间】:2013-03-21 07:23:36
【问题描述】:

我在屏幕上有一个小部件,单击小部件的按钮可启用/禁用广播接收器...但是当我稍微转动手机时..小部件上的所有值都会重置并向用户提供错误信息...我尝试了大多数方法来防止这种情况,如下所示:

  1. 在清单中添加了 android:configChanges="orientation|screenSize"

  2. 在mainavtivity中添加了这个方法

    @覆盖 公共无效 onConfigurationChanged(配置 newConfig){ super.onConfigurationChanged(newConfig); setContentView(R.layout.widget_layout); }

  3. 我也看到了使用 onSaveInstanceState 等的建议,但我无法通过 remoteviews 方法从我的小部件中获取 textview 数据来保存它.. 任何其他方式

---- 这是代码 ----------

在清单中...

<receiver android:name="MyWidgetProvider"  >
            <intent-filter >
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.makelifesimple.autopickmobiletracker.MyWidgetProvider.ACTION_WIDGET_ACTIVATE"/>
                <action android:name="com.makelifesimple.autopickmobiletracker.MyWidgetProvider.ACTION_WIDGET_DEACTIVATE"/>

           </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_info" />
        </receiver>

        <activity
            android:name="com.makelifesimple.autopickmobiletracker.MainActivity"
            android:configChanges="orientation|screenSize"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

--- 在 MyWidgetProvider 中---

public class MyWidgetProvider extends AppWidgetProvider {

    public static String ACTION_WIDGET_ACTIVATE = "ActivatePickup";
    public static String ACTION_WIDGET_DEACTIVATE = "DeactivatePickup";


    RemoteViews remoteViews;
  @Override
  public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {

        Toast.makeText(context, "in onupdate", Toast.LENGTH_SHORT).show();

        remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);

        Intent active = new Intent(context, MyWidgetProvider.class);
        active.setAction(ACTION_WIDGET_ACTIVATE);
        PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0);
        remoteViews.setOnClickPendingIntent(R.id.button1, actionPendingIntent);

        active = new Intent(context, MyWidgetProvider.class);
        active.setAction(ACTION_WIDGET_DEACTIVATE);
        actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0);
        remoteViews.setOnClickPendingIntent(R.id.button2, actionPendingIntent);

        appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);

  }  

  @Override
  public void onEnabled(Context context){
      Toast.makeText(context, "in enables", Toast.LENGTH_SHORT).show();
      context.startService(new Intent(context, MyWidgetProvider.class));
  }

  @Override
  public void onDisabled(Context context){
      Toast.makeText(context, "in disable", Toast.LENGTH_SHORT).show();
      context.stopService(new Intent(context, MyWidgetProvider.class));
  }



  @Override
  public void onReceive(Context context, Intent intent) {
      Toast.makeText(context, "in onRecive", Toast.LENGTH_SHORT).show();
      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
     if (intent.getAction().equals(ACTION_WIDGET_ACTIVATE)) {

          ComponentName receiver = new ComponentName(context, PhoneCallReceiver.class);
          PackageManager pm = context.getPackageManager();
          pm.setComponentEnabledSetting(receiver,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
          //remoteViews.setTextViewText(R.id.button1,"ACTIVATED");
          remoteViews.setTextViewText(R.id.textView2,"ACTIVE");

      } else if (intent.getAction().equals(ACTION_WIDGET_DEACTIVATE)) {

          ComponentName receiver = new ComponentName(context, PhoneCallReceiver.class);
          PackageManager pm = context.getPackageManager();
          pm.setComponentEnabledSetting(receiver,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);

          remoteViews.setTextViewText(R.id.textView2,"INACTIVE");

          Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
          headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
          headSetUnPluggedintent.putExtra("state", 0); // 0 = unplugged  1 = Headset with microphone 2 = Headset without microphone
          headSetUnPluggedintent.putExtra("name", "Headset");
          context.sendOrderedBroadcast(headSetUnPluggedintent, null);

      } 

        Intent active = new Intent(context, MyWidgetProvider.class);
        active.setAction(ACTION_WIDGET_ACTIVATE);
        PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0);
        remoteViews.setOnClickPendingIntent(R.id.button1, actionPendingIntent);

        active = new Intent(context, MyWidgetProvider.class);
        active.setAction(ACTION_WIDGET_DEACTIVATE);
        actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0);
        remoteViews.setOnClickPendingIntent(R.id.button2, actionPendingIntent);


      ComponentName thisWidget = new ComponentName( context, MyWidgetProvider.class );
      AppWidgetManager.getInstance( context ).updateAppWidget(thisWidget, remoteViews );

  }

} 

我在这里缺少什么.......PLS PLSSSSSSSSSS 帮助

【问题讨论】:

  • 能否请您发布密钥代码?另外,您是指主屏幕上的 AppWidget 还是 Activity(或其他)中的某种按钮?
  • 我的意思是小部件上的按钮......它们会在方向更改时自动设置回初始值
  • 任何答案有帮助吗?如果是这样,您可能想打勾并投赞成票;如果不是,您可以说明原因,我们可能会提供更多帮助...

标签: android android-widget widget


【解决方案1】:

依靠小部件提供程序中的onUpdate 来做更多的事情而不是捕捉小部件的创建和删除是非常冒险的。其他一切都应该从其他地方进行管理,通常是从onUpdate 开始的服务或线程。

然后您会捕获方向变化(通过各种方法,无论是来自触发服务或其他线程的活动或广播接收器),这将需要重做您在onUpdate 中的代码。

其他看点:

【讨论】:

  • 为什么投反对票?请在评论中告诉我我的错误,以便我改进答案,谢谢!
【解决方案2】:

这段代码有几个错误。

首先,您的onEnabledonDisabled 方法尝试将AppWidgetProvider 视为服务。不是:它是BroadcastReceiver,因此这些调用将失败,可能会终止您的应用。

但是,这不会发生。您已经覆盖了onReceive,而没有调用super 方法,因此根本不会调用任何其他方法。

在尝试执行其他任何操作之前修复这些错误。您的 onEnabledonDisabled 方法应该为空,您的 onReceive 应该如下所示,没有您现在拥有的重复的小部件更新代码。

if (ACTION_WIDGET_ACTIVATE.equals(intent.getAction()) {
    ...
} else if (ACTION_WIDGET_DEACTIVATE.equals(intent.getAction()) {
    ...
} else {
    super.onReceive(context, intent);
}

【讨论】:

  • 为什么要在onReceive()中实现编码?我见过很多代码,其中大多数都使用了onEnabled &amp; onDisabled。小部件是一个广播接收器,但这并不需要实现onReceive 中的所有编码。如果是这样,那么为什么AppWidgetProvider 类中提供了 onEnabled 和 onDeleted 方法?只是看看,什么都不做?
【解决方案3】:

正如此处发布的:After orientation change buttons on a widget are not responding 您可以通过在每次更新时应用所有小部件更改(包括按钮单击处理程序)来避免这种情况。

【讨论】:

    【解决方案4】:

    对于 AppWidgets,必须实现 onUpdate 以重绘小部件的内容。

    【讨论】:

    • onUpdate 没有被调用来改变方向
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多