我不是第一个遇到旋转调用onConfigurationChanged问题的人.但是由于常见的解决方案是在清单中设置configChanges ="keyboardHidden | orientation",这对我没有帮助,我发布这个问题而不管成千上万的"类似"问题.
这是一个简单的小部件,可在单击时打开和关闭铃声音量.它工作正常,直到屏幕旋转,之后点击没有任何反应.
为了解决这个问题,我想抓住onConfigurationChanged,但它永远不会被调用!我从来没有看到来自onConfigurationChanged的日志消息,但我确实在日志"I/ActivityManager(63):Config changed:"中看到另一条消息,表明配置发生了变化,并且期望调用onConfigurationChanged是合理的. .
请帮忙 :)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="aa.android.x10.mini.mywidget" android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon"
android:label="@string/app_name">
<receiver android:name="MyWidgetProvider" android:label="My Widget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.ACTION_BATTERY_CHANGED" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/widget_info" />
</receiver>
<service android:name=".UpdateWidgetService"
android:configChanges="keyboardHidden|orientation"></service>
<activity android:name=".Test"></activity>
</application>
<uses-sdk android:minSdkVersion="7" />
</manifest>
Run Code Online (Sandbox Code Playgroud)
WidgetProvider:包aa.android.x10.mini.mywidget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
public class MyWidgetProvider extends AppWidgetProvider
{
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
{
Log.i("MyWidgetProvider onUpdate", "#### CALLED!");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(), 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.TextView01, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
context.startService(intent);
}
}
Run Code Online (Sandbox Code Playgroud)
服务:包aa.android.x10.mini.mywidget;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.res.Configuration;
import android.media.AudioManager;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;
public class UpdateWidgetService extends Service
{
@Override
public void onStart(Intent intent, int startId)
{
Log.i("UpdateWidgetService", "#### CALLED!");
String state = null;
AudioManager mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
if (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL )
{
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
mAudioManager.setStreamVolume(AudioManager.STREAM_RING,mAudioManager.getStreamMaxVolume(AudioManager.STREAM_RING),AudioManager.VIBRATE_SETTING_ON);
state = "ON";
}
else
{
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
mAudioManager.setStreamVolume(AudioManager.STREAM_RING,0,AudioManager.VIBRATE_SETTING_ON);
state = "OFF";
}
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
int[] appWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds.length > 0)
{
for (int widgetId : appWidgetIds)
{
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.widget_layout);
remoteViews.setTextViewText(R.id.TextView01, "\n" +" "+ state);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
stopSelf();
}
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
Log.i("onConfigurationChanged", "##### CALLED! #####");
super.onConfigurationChanged(newConfig);
}
}
Run Code Online (Sandbox Code Playgroud)
旋转屏幕时记录:
I/WindowManager( 63): Setting rotation to 1, animFlags=0
I/ActivityManager( 63): Config changed: { scale=1.0 imsi=310/260 loc=en_US touch=3 keys=2/1/1 nav=3/1 orien=2 layout=17}
I/UsageStats( 63): Unexpected resume of com.android.launcher while already resumed in com.android.launcher
Run Code Online (Sandbox Code Playgroud)
乔恩,
onConfigurationChanged()不是真的意味着Services.由于Services没有用户界面,因此无法保证onConfigurationChanged()无法可靠地启动.最好坚持使用Activity,因为Activities保证有用户界面.如果您担心您的Widget重新调整方向更改,那么最终是包含要处理的Activity的工作.这意味着如果Activity不旋转,您的Widget将不会自行重定向.
但是,如果您仍需要自己管理配置更改,则需要手动执行检查DefaultDisplay,如果方向发生更改,则会自动更改.这个简单的检查工作如下:
Display display = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if (display.getWidth() > display.getHeight())
// In Landscape...
else if (display.getWidth() < display.getHeight())
// In Portrait...
Run Code Online (Sandbox Code Playgroud)
现在,您描述的问题,虽然它在Orientation更改时显现,但它并不是特定的Orientation Change问题.如果您查看代码onUpdate(),您将看到您一次只处理一个小部件.这个问题是方向更改的默认行为会破坏所有UI并重新创建它们.由于对Widget的多个副本的所有更新都会立即发生,并且您无法确定包含您的小部件的Activity将如何处理方向更改,因此您应该考虑所有可能的appWidgetIds.以下可能有所帮助:
for (int i : appWidgetIds) {
int widgetId = appWidgetIds[i];
// Set the RemoteViews for the Widget
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_layout);
// Set the Pending Intent
Intent intent = new Intent(context.getApplicationContext(),
UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(),
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.TextView01, pendingIntent);
// Update the individual widget
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
FuzzicalLogic
| 归档时间: |
|
| 查看次数: |
4747 次 |
| 最近记录: |