在将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>
[...]
答案 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);
。