当设置AltBeacons RangeNotifier时,Android WebView loadUrl不再工作(在4.4.4中)

时间:2015-01-11 16:42:40

标签: android webview

在将AltBeacons RangeNotifier设置为我的活动后,我在加载URL(WebView.loadUrl)时遇到问题。当我不激活RangeNotifier时,我的WebView会按原样处理每个URL。但是当我开始收听信标时,我的webview中的每个loadUrl调用都没有结束,我只看到一个白页。

我认为,这在某种程度上是不同线程的问题,它试图使用webview ...

Android 5中没有出现此问题。+。

任何人都可以帮助我吗?有没有人有同样的问题?

编辑: 非常感谢你的回答大卫。但不幸的是,这似乎并没有解决问题。

以下活动不适用于我的Android 4.4.4 Nexus 7(webview永远不会停止加载!只是不时,它开始加载,但永远不会结束)。我刚刚删除了所有与此无关的代码(这就是为什么有些方法似乎有点不必要)。

我注意到,我收到FBIOGET_FSCREENINFO失败错误。曾经,它工作正常(但不是我试过的其他100次: - /)

编辑2:我更新了我的代码,以便我的webview确实应该有足够的时间来加载网址。我现在每次都加载不同的URL。当我打开Chrome并在平板电脑上加载相同的网址时,它们的加载速度非常快(正如预期的WIFI)。我注意到,我收到了“本地抽奖警告”。我真的不明白这一点。在所有其他设备上,作品非常棒。但是在使用4.4.4的Nexus 7上,这种奇怪的行为让我很头疼:(

public class Main extends Activity implements BeaconConsumer {
    /**
     * General fields
     */
    public WebView mWv;
    public ProgressBar mProgressBar;

    protected static final String TAG = "printr";
    protected AlertDialog mDialog = null;


    private Activity mContext;
    private int mCounter = 0;

    /**
     * BLE / Beacon Fields
     */
    private BluetoothAdapter mBluetoothAdapter;
    private BeaconManager mBeaconManager = BeaconManager.getInstanceForApplication(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContext = this;

        mProgressBar = (ProgressBar) findViewById(R.id.progressBar_webView);
        mProgressBar.setVisibility(View.GONE);

        // Configure WebView
        mWv = (WebView) findViewById(R.id.detail_ww);
        mWv.setWebChromeClient(new WebChromeClient());
        mWv.setWebViewClient(new WebViewClient() {
            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                super.onReceivedError(view, errorCode, description, failingUrl);
                mProgressBar.setVisibility(View.GONE);
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                if(null != url && !("").equals(url)) {
                    if(!url.startsWith("file:")) {
                        //show loading wheel on top of screen
                        mProgressBar.setVisibility(View.VISIBLE);
                    }
                }
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                Log.d(TAG, "FINISHED LOADING PAGE (" + url + ")!");
                mProgressBar.setVisibility(View.GONE);
            }
        });


        // Start Beacon Listener
        startBeaconManager();
    }

    private void loadUrl(String url) {
        if(url != null && !("").equals(url)) {
            Log.d(TAG, "Load URI: " + url);
            mWv.stopLoading();
            mWv.loadUrl(url);
        }
    }

    protected void loadContentForWebView() {
        //maybe do some other stuff
        if(mCounter == 1) {
            loadUrl("http://www.stackoverflow.com");
        } else if(mCounter < 21) {
            loadUrl("http://www.google.com");
        } else if(mCounter < 41) {
            loadUrl("http://www.amazon.com");
        } else loadUrl("http://www.yahoo.com");

    }

    private void startBeaconManager() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            // Device does not support Bluetooth
            Toast.makeText(
                    mContext,
                    "Ihr Gerät unterstützt leider kein Bluetooth 4.0. Die App kann daher nicht vollumfänglich genutzt werden.",
                    Toast.LENGTH_LONG).show();
        } else {
            if (!mBluetoothAdapter.isEnabled()) {

                if(mBeaconManager.isBound(this)) {
                    mBeaconManager.unbind(this);
                }

                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, Constants.REQUEST_ENABLE_BT);
            } else {
                if (!mBeaconManager.isBound(this)) {
                    // bind beacon manager
                    //Log.d(TAG, "Bind beacon manager.");
                    mBeaconManager.bind(this);
                }
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // settings saved for example
        switch(requestCode) {
        case Constants.REQUEST_ENABLE_BT:
            if(mBluetoothAdapter.isEnabled()) {
                startBeaconManager();
            } else {
                Toast.makeText(
                        mContext,
                        "Bitte aktivieren Sie Bluetooth, damit Sie Informationen empfangen können.",
                        Toast.LENGTH_LONG).show();
            }
            break;
        }
    }

    @Override
    public void onBeaconServiceConnect() {
        /**
         * Ranging
         */

        // Set custom scan periods
        mBeaconManager.setBackgroundScanPeriod(Constants.SCAN_PERIOD);
        mBeaconManager.setForegroundScanPeriod(Constants.SCAN_PERIOD);
        // mBeaconManager.setBackgroundBetweenScanPeriod(60000l);

        try {
            mBeaconManager.updateScanPeriods();
        } catch (RemoteException e) {
            Log.e(TAG, "Error setting scan perion: " + e.getMessage());
        }

        // add beacon layouts for estimote, kontakt beacons, drop beacons etc.
        mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(Constants.BEACON_LAYOUT_ALT_BEACON));
        mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(Constants.BEACON_LAYOUT_IOS));

        mBeaconManager.setRangeNotifier(new RangeNotifier() {
            @Override
            public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
                Log.d(TAG, "counter: "+mCounter);
                mCounter++;
                getNearestBeaconAndPresent();
            }
        });
        try {
            mBeaconManager.startRangingBeaconsInRegion(new Region(Constants.MY_REGION_ID, null, null, null));
        } catch (RemoteException e) {}
    }

    protected void getNearestBeaconAndPresent() {
        //do some calculations...
        presentContent();
    }

    private void presentContent() {
        runOnUiThread(new Runnable() {
            public void run() {
                if(mCounter % 20 == 0 || mCounter == 1) {
                    //only load every 20 sec (with wifi!) - to be sure the webview should have finished loading...
                    mContext.setTitle("Counter: "+ mCounter);
                    loadContentForWebView();
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        //Log.d(TAG, "onDestroy MAIN");
        super.onDestroy();
        mBeaconManager.unbind(this);
    }
}

清单:

[...]
<uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="19" />

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:allowBackup="true"
        android:hardwareAccelerated="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".Splash"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"
            android:theme="@style/FullscreenTheme" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".ChooseEvent"
            android:label="@string/title_activity_login" >
        </activity>
        <activity
            android:name=".Main"
            android:parentActivityName=".ChooseEvent"
            android:label="@string/title_activity_main" >
        </activity>
        <activity
            android:name=".SetPreferenceActivity"
            android:label="@string/action_settings" />
        <activity
            android:name=".About"
            android:label="@string/title_activity_about" >
        </activity>
    </application>
[...]

2 个答案:

答案 0 :(得分:1)

如果您需要在AndroidBeaconLibrary的任何回调中操作UI,您必须将其包装在这样的块中:

runOnUiThread(new Runnable() {
  public void run() {
    // put view manipulation code here
  }
}

答案 1 :(得分:0)

接收信标范围回调的代码如下所示:

        @Override
        public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
            Log.d(TAG, "counter: "+mCounter);
            mCounter++;
            getNearestBeaconAndPresent();
        }

了解当信标可见时,此代码将每秒调用一次。在getNearestBeaconsAndPresent()方法内部,有一个调用将URL加载到Web视图中。尽管只有在mCounter % 3 == 0时才会执行此操作,但这仍然会每3秒重新加载一次Web视图。

我的猜测是,在设置此URL以允许页面完全加载和呈现之间没有足够的时间。您可以尝试更少发生此事(例如将其更改为mCounter % 30 == 0,或者您可以检查网址是否已更改,并且只有在网址实际更改时才调用mWv.stopLoading(); mWv.loadUrl(url);