在与configChanges旋转onConfigurationChanged不叫=" keyboardHidden |取向"组? [英] onConfigurationChanged not called at rotation with configChanges="keyboardHidden|orientation" set?

查看:134
本文介绍了在与configChanges旋转onConfigurationChanged不叫=" keyboardHidden |取向"组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不是有越来越onConfigurationChanged叫在轮换问题的第一个。但是,由于常见的解决方案是设置configChanges =keyboardHidden |方向
在清单中,这并不能帮助我,无论成千上万的相似的人的我张贴了这个问题。

这是一个简单的小工具单击时打开振铃音量或关闭。直到屏幕旋转,它工作得很好,没有什么发生在点击后。

要解决这个问题,我要赶onConfigurationChanged,但它永远不会被调用!
我从来没有看到从onConfigurationChanged日志消息,但是我确实看到另一条消息在日志中的I / ActivityManager(63):配置改变:这表明,配置文件会改变,这将是合理的期望onConfigurationChanged通话

请帮忙:)

清单:

 <?XML版本=1.0编码=UTF-8&GT?;
<清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    包=aa.android.x10.mini.mywidget安卓版code =1
    机器人:=的versionName1.0>
<应用机器人:图标=@绘制/图标
             机器人:标签=@字符串/ APP_NAME>    <接收机器人:名字=MyWidgetProvider机器人:标签=我的窗口小部件>
        &所述;意图滤光器>
            <作用机器人:名字=android.appwidget.action.APPWIDGET_UPDATE/>
            <作用机器人:名字=android.appwidget.action.ACTION_BATTERY_CHANGED/>
        &所述; /意图滤光器>
        <元数据机器人:名字=android.appwidget.provider
                   机器人:资源=@ XML / widget_info/>
    < /接收器>
    <服务机器人:名字=。UpdateWidgetService
             机器人:configChanges =keyboardHidden |方向>< /服务>
    <活动机器人:名字=测试>< /活性GT;    < /用途>
    <采用-SDK安卓的minSdkVersion =7/>< /清单>


WidgetProvider:
    包aa.android.x10.mini.mywidget;

 进口android.app.PendingIntent;
进口android.appwidget.AppWidgetManager;
进口android.appwidget.AppWidgetProvider;
进口android.content.Context;
进口android.content.Intent;
进口android.util.Log;
进口android.widget.RemoteViews;公共类MyWidgetProvider扩展AppWidgetProvider
{
@覆盖
公共无效的onUpdate(上下文的背景下,AppWidgetManager appWidgetManager,
        INT [] appWidgetIds)
{
    Log.i(MyWidgetProvider的onUpdate,####叫来!);    RemoteViews remoteViews =新的RemoteViews(context.getPackageName()
            R.layout.widget_layout);
    意向意图=新意图(context.getApplicationContext(),UpdateWidgetService.class);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,appWidgetIds);    的PendingIntent的PendingIntent = PendingIntent.getService(context.getApplicationContext(),0,意向,
                                                            PendingIntent.FLAG_UPDATE_CURRENT);    remoteViews.setOnClickPendingIntent(R.id.TextView01,的PendingIntent);    appWidgetManager.updateAppWidget(appWidgetIds,remoteViews);    context.startService(意向);
    }
}


服务:
    包aa.android.x10.mini.mywidget;

 进口android.app.Service;
进口android.appwidget.AppWidgetManager;
进口android.content.Intent;
进口android.content.res.Configuration;
进口android.media.AudioManager;
进口android.os.IBinder;
进口android.util.Log;
进口android.widget.RemoteViews;公共类UpdateWidgetService延伸服务
{
@覆盖
公共无效调用onStart(意向意图,诠释startId)
{
    Log.i(UpdateWidgetService,####叫来!);    字符串状态= NULL;    AudioManager mAudioManager =(AudioManager)getSystemService(AUDIO_SERVICE);    如果(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);
        状态=ON;
    }
    其他
    {
        mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
        mAudioManager.setStreamVolume(AudioManager.STREAM_RING,0,AudioManager.VIBRATE_SETTING_ON);
        状态=OFF;
    }    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());    INT [] = appWidgetIds intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
    如果(appWidgetIds.length大于0)
    {
        对于(INT为widgetid:appWidgetIds)
        {
            RemoteViews remoteViews =新的RemoteViews(getPackageName(),R.layout.widget_layout);
            remoteViews.setTextViewText(R.id.TextView01,\\ n++状态);
                appWidgetManager.updateAppWidget(为widgetid,remoteViews);
            }
            stopSelf();
        }
        super.onStart(意向,startId);
    }    @覆盖
    公众的IBinder onBind(意向意图)
    {
        返回null;
    }    @覆盖
    公共无效onConfigurationChanged(配置NEWCONFIG)
    {
        Log.i(onConfigurationChanged,##### CALLED #####!);
        super.onConfigurationChanged(NEWCONFIG);
    }
}


日志旋转屏幕时:

  I /窗口管理器(63):旋转设置为1,animFlags = 0
I / ActivityManager(63):配置改变:{规模= 1.0 IMSI =二百六十分之三百十LOC = EN_US触摸= 3键= 2/1/1 = NAV 3/1 =广州澳凌布局2 = 17}
I / usagestats机(63):com.android.launcher意外的简历,同时已在com.android.launcher恢复


解决方案

乔恩,

onConfigurationChanged()是不是真的意味着服务。由于服务没有UI,没有保证 onConfigurationChanged()将无法可靠地触发。最好是在活动要坚持这个,因为活动都保证有一个用户界面。如果你关心你的部件重新调整,以改变方向时,其结果是包含活动来处理工作。这意味着如果活动不转动,小部件将无法重新定位自己。

如果,但是,你仍然需要进行管理配置改变自己,那么你需要手动做你检查对 DefaultDisplay 自动改变,如果方向变化。这种简单的检查工作原理如下:

 显示显示=((窗口管理器)mContext.getSystemService(Context.WINDOW_SERVICE))getDefaultDisplay()。
如果(display.getWidth()> display.getHeight())
    //在风景...
否则如果(display.getWidth()&所述; display.getHeight())
    //在人像...

现在,你的描述,而它表现的时候方向变化,这是没有具体的方向变化问题的问题。如果你看一下code为你的的onUpdate(),你会看到你一次只能处理一个小部件。这样做的问题是改变方向时的默认行为破坏了所有的用户界面和重新创建它们。由于所有更新一个Widget一次发生,你不能确定握着你的插件的活动是怎么回事处理方向改变的多个副本,你应该考虑所有可能的appWidgetIds的。下面可以帮助:

 的for(int我:appWidgetIds){
    INT为widgetid = appWidgetIds [I]
//设置为插件的RemoteViews
    RemoteViews remoteViews =新的RemoteViews(context.getPackageName(),R.layout.widget_layout);
//设置待意图
    意向意图=新意图(context.getApplicationContext()
                               UpdateWidgetService.class);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,appWidgetIds);    的PendingIntent的PendingIntent = PendingIntent.getService(context.getApplicationContext()
                     0,意向,PendingIntent.FLAG_UPDATE_CURRENT);    remoteViews.setOnClickPendingIntent(R.id.TextView01,的PendingIntent);
//更新个别小窗口
    appWidgetManager.updateAppWidget(为widgetid,remoteViews);
}

希望这有助于。

FuzzicalLogic

I'm not the first one to have problems with getting onConfigurationChanged called at rotation. But since the common solution is to set configChanges="keyboardHidden|orientation" in the manifest, and that does not help me, I posting this question regardless of the thousands of "similar" ones.

This is a simple widget that turns the ringer volume on and off when clicked. It works fine until the screen is rotated, after that nothing happens on click.

To deal with this issue I want to catch onConfigurationChanged, but it never gets called! I never get to see the log message from onConfigurationChanged, I do however see another message in the log "I/ActivityManager( 63): Config changed: " indicating that the configuration gets changed and that it would be reasonable to expect a call to onConfigurationChanged.

Please help :)

Manifest:

<?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>   


WidgetProvider: package 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);  
    }  
}  


Service: package 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);
    }
}  


Log when rotating the screen:

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 

解决方案

Jon,

onConfigurationChanged() is not really meant for Services. As Services do not have a UI, there is no guarantee that onConfigurationChanged() will not fire dependably. It is best to stick this in an Activity, as Activities are guaranteed to have a User Interface. If you are concerned about your Widget realigning to an orientation change, that is ultimately a job for the containing Activity to handle. This means if the Activity does not rotate, your Widget will not reorient itself.

If, however, you still need to manage configuration changes yourself, then you need to do your checks manually against the DefaultDisplay which automatically changes if the orientation changes. This simple check works as follows:

Display display = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if (display.getWidth() > display.getHeight())
    // In Landscape...
else if (display.getWidth() < display.getHeight())
    // In Portrait...

Now, the issue you describe, while it manifests itself when the Orientation changes, it is not specifically an Orientation Change problem. If you look at the code for your onUpdate(), you will see that you are only handling one widget at a time. The issue with this is that the default behavior of an orientation change destroys all UIs and recreates them. Since all updates to multiple copies of a Widget happen at once and you cannot determine how the Activity that holds your widget is going to handle orientation changes, you should account for all of your possible appWidgetIds. The following may help:

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);
}

Hope this helps.

FuzzicalLogic

这篇关于在与configChanges旋转onConfigurationChanged不叫=&QUOT; keyboardHidden |取向&QUOT;组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆