Using a BroadcastReceiver to update a ProgressBar - java

I am trying to update a ProgressBar from a Service task. I implemented a BroadcastReceiver so that I can interact with the UI thread. I update the ProgressBar in the main activity, and receive the data from the MyService activity. The MyService activity executes an Async task and updates the intent that should be sent back in the OnProgressUpdate method.
Here is my code:
MainActivity:
package com.example.services;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.ProgressBar;
import static android.content.Intent.ACTION_ATTACH_DATA;
public class MainActivity extends AppCompatActivity {
private MyBroadRequestReceiver receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
receiver = new MyBroadRequestReceiver();
registerReceiver( receiver, filter);
}
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
//pb.setProgress();
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
public class MyBroadRequestReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
int progress = intent.getFlags();
pb.setProgress(progress);
}
}
}
MyService:
package com.example.services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.AsyncTask;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class MyService extends Service {
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
doSomethingRepeatedly();
try {
new DoBackgroundTask().execute(
new URL("http://www.amazon.com/somefiles.pdf"),
new URL("http://www.wrox.com/somefiles.pdf"),
new URL("http://www.google.com/somefiles.pdf"),
new URL("http://www.learn2develop.net/somefiles.pdf"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if (timer != null){
timer.cancel();
}
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
private void doSomethingRepeatedly() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.d("MyService", String.valueOf(++counter));
}
}, 0, UPDATE_INTERVAL);
}
private class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalBytesDownloaded = 0;
for (int i = 0; i < count; i++) {
totalBytesDownloaded += DownloadFile(urls[i]);
//Intent broadcastIntent = new Intent();
//broadcastIntent.setAction(Intent.ACTION_ATTACH_DATA);
//sendBroadcast(broadcastIntent);
publishProgress((int) (((i + 1) / (float) count) * 100));
}
return totalBytesDownloaded;
}
protected void onProgressUpdate(Integer... progress) {
Log.d("Downloading files", String.valueOf(progress[0]) + "% downloaded");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.example.services.MainActivity");
//broadcastIntent.putExtra("progress",progress);
broadcastIntent.setFlags(progress[0]);
sendBroadcast(broadcastIntent);
Toast.makeText(getBaseContext(),
String.valueOf(progress[0]) + "% downloaded-"+counter,
Toast.LENGTH_LONG).show();
}
protected void onPostExecute(Long result) {
Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
Toast.LENGTH_LONG).show();
//stopSelf();
}
}
private int DownloadFile(URL url) {
try {
//---simulate taking some time to download a file---
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//---return an arbitrary number representing
// the size of the file downloaded---
return 100;
}
}
Please take a look at my onProgressUpdate and tell me if I am doing this correclty. My ProgressBar is not being updated at all.

Because you don't startService ononCreate() Method. Service will not run.

Firs of all this is not good solution to the problem your solving. Please go through Google Android docs Backgournd guide
I suggest you should switch to DownloadManager.

Your intent filter is defining to "ACTION_ATTACH_DATA"
IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
So, send your broadcast like this:
Intent i = new Intent(ACTION_ATTACH_DATA);
sendBroadcast(i);
Also, don't forget to unregister the broadcast at onDestroy

Related

How to make BLE scan and MQTT publish work in background Android Studio Java

I want make some project where Android can scan nearby Beacon/BLE and send it using MQTT. But I want the service to work in the background if the service work in the foreground it will interrupt the scanning process when screen is off.
This is my code for scanning:
package com.example.mqtt_active;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import java.nio.charset.StandardCharsets;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private Button turnon, changeLayout;
MqttAndroidClient client;
private boolean state=false;
private BluetoothAdapter bluetoothAdapter;
public static final int REQUEST_ACCESS_COARSE_LOCATION = 1;
public static final int REQUEST_ENABLE_BLUETOOTH = 11;
public static String mqtt_server,mqtt_port,mqtt_id;
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
Log.d("Logger", "On Create Android");
turnon = findViewById(R.id.turnon);
changeLayout = findViewById(R.id.mqttSet);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
textView = findViewById(R.id.textView4);
textView.setText("id "+mqtt_id+" port "+mqtt_port+" server "+mqtt_server);
client = new MqttAndroidClient(this.getApplicationContext(), "tcp://"+mqtt_server+":"+mqtt_port,mqtt_id);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
stateCheck();
Log.d("Logger", "State Check");
handler.postDelayed(this, 1000);
}
}, 1000);
// final Handler handlerStop = new Handler();
// handlerStop.postDelayed(new Runnable() {
// #Override
// public void run() {
// bluetoothAdapter.cancelDiscovery();
// Log.d("Logger", "Cancel Dsicovery");
// handlerStop.postDelayed(this, 2000);
// }
// }, 2000);
turnon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!state){
turnon.setText("Turn Off");
Log.d("Logger", "Turn On State");
// if (bluetoothAdapter!=null & bluetoothAdapter.isEnabled()) {
// if(checkCoarsePermission()){
// bluetoothAdapter.startDiscovery();
// }
// }
if(mqtt_server!=null||mqtt_id!=null||mqtt_port!=null){
try {
Log.d("Logger", "Try ");
IMqttToken token = client.connect();
token.setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d("Logger", "Connect MQTT");
Toast.makeText(MainActivity.this,"connected!!",Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.d("Logger", "Connect Failed");
Toast.makeText(MainActivity.this,"connection failed!!",Toast.LENGTH_LONG).show();
}
});
} catch (MqttException e) {
e.printStackTrace();
Log.d("Logger", "error"+e);
}}
state = true;
}else{
turnon.setText("Turn On");
state = false;
// bluetoothAdapter.cancelDiscovery();
}
}
});
changeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,MqttActivity.class));
}
});
}
public void stateCheck(){
if (state){
if (bluetoothAdapter!=null & bluetoothAdapter.isEnabled()) {
if(checkCoarsePermission()){
Log.d("Logger", "Discover");
bluetoothAdapter.startDiscovery();
}
}
}
// else {
// Log.d("Logger", "Cancel");
// bluetoothAdapter.cancelDiscovery();
// }
}
private boolean checkCoarsePermission(){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_ACCESS_COARSE_LOCATION);
return false;
}else {
return true;
}
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(devicesFoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
registerReceiver(devicesFoundReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));
registerReceiver(devicesFoundReceiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(devicesFoundReceiver);
}
private final BroadcastReceiver devicesFoundReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action= intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
String RSSI = String.valueOf(rssi);
Toast.makeText(context.getApplicationContext(),"rssi "+RSSI+" "+device.getAddress(),Toast.LENGTH_SHORT).show();
Log.d("Logger", "Recive data "+device.getAddress());
if(mqtt_server!=null||mqtt_id!=null||mqtt_port!=null){
try {
Log.d("Logger", "Sending data");
String payload = "rssi:"+RSSI+"mac:"+device.getAddress();
client.publish("test",payload.getBytes(),0,false);
} catch ( MqttException e) {
e.printStackTrace();
Log.d("Logger", "Error Sending "+e);
}}
}else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
}else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
}
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_ACCESS_COARSE_LOCATION:
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,"ALLOWED", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this,"Forbidden",Toast.LENGTH_SHORT).show();
} break;
}
}
}
App Flow:
Insert MQTT server, port, id, topic.
Turn on the proccess.
Android scan BLE/Beacon
Android sending MAC/RSSI to MQTT
I hope someone can help to guide me, on how to make the application run in the background?
I'm a beginner, and I don't understand how to implement background service in my application. Please help me!
You need to implement a foreground service that will handle your ble scanning and MQTT logic.
See this article with an overview of how to do it. Depending on your build/target SDK, the implementation will vary.

Update the progress of a ProgressBar while using a Service?

I am trying to update a progress bar while downloading a file, but in my Service task I do not have any access to the UI. This means I cannot find the ProgressBar element using findViewByID in order to update the ProgressBar. Here is the relevant code:
MainActivity:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
}
MyService Class:
package com.example.services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.AsyncTask;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class MyService extends Service {
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
doSomethingRepeatedly();
try {
new DoBackgroundTask().execute(
new URL("http://www.amazon.com/somefiles.pdf"),
new URL("http://www.wrox.com/somefiles.pdf"),
new URL("http://www.google.com/somefiles.pdf"),
new URL("http://www.learn2develop.net/somefiles.pdf"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if (timer != null){
timer.cancel();
}
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
private void doSomethingRepeatedly() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.d("MyService", String.valueOf(++counter));
}
}, 0, UPDATE_INTERVAL);
}
private class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalBytesDownloaded = 0;
for (int i = 0; i < count; i++) {
totalBytesDownloaded += DownloadFile(urls[i]);
publishProgress((int) (((i + 1) / (float) count) * 100));
}
return totalBytesDownloaded;
}
protected void onProgressUpdate(Integer... progress) {
Log.d("Downloading files", String.valueOf(progress[0]) + "% downloaded");
Toast.makeText(getBaseContext(),
String.valueOf(progress[0]) + "% downloaded-"+counter,
Toast.LENGTH_LONG).show();
}
protected void onPostExecute(Long result) {
Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
Toast.LENGTH_LONG).show();
//stopSelf();
}
}
private int DownloadFile(URL url) {
try {
//---simulate taking some time to download a file---
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//---return an arbitrary number representing
// the size of the file downloaded---
return 100;
}
}
Basically, I want to update the ProgressBar in my MainActivity by using the bytesDownloaded variable in my MyService class, but I'm not sure how to handle the Async call in my MainActivity. If that is even possible.
Thanks!

When using Floating Bubble as a Background Service to take a screenshot of Live Screen. Getting two Errors

enter code here BackgroundService-
private void addNewBubble ()//ERROR , Expression expected and Missing ';' token{
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
//here is all the science of params
final WindowManager.LayoutParams myParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
PixelFormat.TRANSLUCENT
);
BubbleLayout bubbleView = (BubbleLayout) LayoutInflater.from(BackgroundService.this).inflate(R.layout.bubble_layout, null);
bubbleView.setLayoutParams(myParams);
bubbleView.setOnBubbleRemoveListener(new BubbleLayout.OnBubbleRemoveListener() {
#Override
public void onBubbleRemoved(BubbleLayout bubble) {
}
});
bubbleView.setOnBubbleClickListener(new BubbleLayout.OnBubbleClickListener() {
#Override
public void onBubbleClick(BubbleLayout bubble) {
Bitmap b = Screenshot.takescreenshotOfRootView(imageView);
imageView.setImageBitmap(b);
main.setBackgroundColor(Color.parseColor("#999999"));
//Toast.makeText(getApplicationContext(), "Clicked !",
// Toast.LENGTH_SHORT).show();
}
});
bubbleView.setShouldStickToWall(true);
bubblesManager.addBubble(bubbleView, 60, 20);
}
}
private void initializeBubblesManager() {
bubblesManager = new BubblesManager.Builder(this)
.setTrashLayout(R.layout.bubble_trash_layout)
.setInitializationCallback(new OnInitializedCallback() {
#Override
public void onInitialized() {
addNewBubble();// ERROR
}
})
.build();
bubblesManager.initialize();
}
}
This is the OnStart method which includes all the methods to create the floating bubble and to make it clickable to take a screenshot. Only addNewBubble is showing errors , whereas when the Floating Bubble code is run on the MainActivity without the creation of BackgroundService it runs fine without any errors.
Any suggestions as to what to do ?
Copy paste this code .I have tested it
import android.content.Intent;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Toast;
import com.txusballesteros.bubbles.BubbleLayout;
import com.txusballesteros.bubbles.BubblesManager;
import com.txusballesteros.bubbles.OnInitializedCallback;
/**
* Created by yohanson on 20/09/17.
*/
public class MainActivity extends AppCompatActivity {
private BubblesManager bubblesManager;
private WindowManager windowManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.add).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkDrawOverlayPermission();
}
});
}
public void checkDrawOverlayPermission() {
/** check if we already have permission to draw over other apps */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
/** if not construct intent to request permission */
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
/** request permission via start activity for result */
startActivityForResult(intent, 2);
}
else
{
initializeBubblesManager();
addNewBubble();
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
/** check if received result code
is equal our requested code for draw permission */
if (requestCode == 2) {
initializeBubblesManager();
addNewBubble();
}
}
private void addNewBubble() {
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//here is all the science of params
final WindowManager.LayoutParams myParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
PixelFormat.TRANSLUCENT
);
BubbleLayout bubbleView = (BubbleLayout)LayoutInflater.from(MainActivity.this).inflate(R.layout.bubble_layout, null);
bubbleView.setLayoutParams(myParams);
bubbleView.setOnBubbleRemoveListener(new BubbleLayout.OnBubbleRemoveListener() {
#Override
public void onBubbleRemoved(BubbleLayout bubble) { }
});
bubbleView.setOnBubbleClickListener(new BubbleLayout.OnBubbleClickListener() {
#Override
public void onBubbleClick(BubbleLayout bubble) {
Toast.makeText(getApplicationContext(), "Clicked !",
Toast.LENGTH_SHORT).show();
}
});
bubbleView.setShouldStickToWall(true);
bubblesManager.addBubble(bubbleView, 60, 20);
}
private void initializeBubblesManager() {
bubblesManager = new BubblesManager.Builder(this)
.setTrashLayout(R.layout.bubble_trash_layout)
.setInitializationCallback(new OnInitializedCallback() {
#Override
public void onInitialized() {
addNewBubble();
}
})
.build();
bubblesManager.initialize();
}
#Override
protected void onDestroy() {
super.onDestroy();
bubblesManager.recycle();
}
}
Call addNewBubble() function in UiThread
runOnUiThread(new Runnable() {
public void run() {
addNewBubble()
}
});
like this.

Getting Beacon Fence Using Awareness API it's take too much time and not accurate

This is my code for getting BeaconFence.It's take too much time and not provide accurate information i fetch two fence lost and found
//BeaconFenceActivity.java
import android.Manifest;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.azilen.awarenessapidemo.R;
import com.google.android.gms.awareness.Awareness;
import com.google.android.gms.awareness.fence.AwarenessFence;
import com.google.android.gms.awareness.fence.BeaconFence;
import com.google.android.gms.awareness.fence.FenceState;
import com.google.android.gms.awareness.fence.FenceUpdateRequest;
import com.google.android.gms.awareness.state.BeaconState;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.ResultCallbacks;
import com.google.android.gms.common.api.Status;
import java.util.Arrays;
import java.util.List;
public class BeaconFenceActivity extends AppCompatActivity {
private GoogleApiClient mGoogleApiClient;
private static final int PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 940;
private TextView txtBeacon;
private static final String BEACON_FENCE_KEY = "BEACON_FENCE_KEY";
private static final int BEACON_ZONE_IN = 2;
private static final int BEACON_ZONE_OUT = 1;
private PendingIntent mPendingIntent;
private BeaconFenceReceiver mBeaconFenceReceiver;
private ProgressDialog mProgress;
//Replace this with app's Google project name
private static final List<BeaconState.TypeFilter> BEACON_TYPE_FILTERS = Arrays.asList
(BeaconState.TypeFilter.with("awarenessapidemo-158205", "beacondemo"));
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_beacon_fence);
mProgress = new ProgressDialog(BeaconFenceActivity.this);
mProgress.setTitle("Geting Near Beacon");
mProgress.setMessage("Please wait..");
txtBeacon = (TextView) findViewById(R.id.txt_fence_beacon);
mGoogleApiClient = new GoogleApiClient.Builder(BeaconFenceActivity.this).addApi(Awareness.API).build();
mGoogleApiClient.connect();
mBeaconFenceReceiver = new BeaconFenceReceiver();
Intent intent = new Intent(BeaconFenceReceiver.BEACON_FENCE_RECEIVER_ACTION);
mPendingIntent = PendingIntent.getBroadcast(BeaconFenceActivity.this, 1, intent, 0);
}
#Override
protected void onStart() {
super.onStart();
getBeaconDetails();
registerReceiver(mBeaconFenceReceiver, new IntentFilter(BeaconFenceReceiver.BEACON_FENCE_RECEIVER_ACTION));
}
#Override
protected void onStop() {
super.onStop();
unregisterFences();
unregisterReceiver(mBeaconFenceReceiver);
}
private void getBeaconDetails() {
mProgress.show();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_ACCESS_FINE_LOCATION);
mProgress.hide();
} else {
AwarenessFence beaconFoundFence = BeaconFence.found(BEACON_TYPE_FILTERS);
AwarenessFence lostFence = BeaconFence.lost(BEACON_TYPE_FILTERS);
AwarenessFence orFence = AwarenessFence.or(lostFence, beaconFoundFence);
Awareness.FenceApi.updateFences(mGoogleApiClient,
new FenceUpdateRequest.Builder()
.addFence(BEACON_FENCE_KEY, orFence, mPendingIntent)
/* .addFence(BEACON_FENCE_KEY, beaconFoundFence, mPendingIntent)
.addFence(BEACON_FENCE_KEY, lostFence, mPendingIntent)
*/
.build()).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Toast.makeText(BeaconFenceActivity.this, "Fence Registered", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(BeaconFenceActivity.this, "Fence Not Registered", Toast.LENGTH_SHORT).show();
}
}
});
mProgress.hide();
}
}
private void unregisterFences() {
Awareness.FenceApi.updateFences(
mGoogleApiClient,
new FenceUpdateRequest.Builder()
.removeFence(BEACON_FENCE_KEY)
.build()).setResultCallback(new ResultCallbacks<Status>() {
#Override
public void onSuccess(#NonNull Status status) {
Toast.makeText(BeaconFenceActivity.this, "Fence Removed", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(#NonNull Status status) {
Toast.makeText(BeaconFenceActivity.this, "Fence Not Removed", Toast.LENGTH_SHORT).show();
}
});
}
public void checkRestart(View view) {
getBeaconDetails();
registerReceiver(mBeaconFenceReceiver, new IntentFilter(BeaconFenceReceiver.BEACON_FENCE_RECEIVER_ACTION));
}
public class BeaconFenceReceiver extends BroadcastReceiver {
public static final String BEACON_FENCE_RECEIVER_ACTION = "com.azilen.awarenessapidemo.activities.fence.BeaconFenceReceiver.BEACON_FENCE_RECEIVER_ACTION";
#Override
public void onReceive(Context context, Intent intent) {
Log.e("Recived", "Received a Beacon Fence Broadcast");
FenceState fenceState = FenceState.extract(intent);
Log.e("FenceState Status:-", String.valueOf(fenceState.getFenceKey()));
if (TextUtils.equals(fenceState.getFenceKey(), BEACON_FENCE_KEY)) {
Log.e("FenceState:-", String.valueOf(fenceState.getCurrentState()));
switch (fenceState.getCurrentState()) {
case FenceState.TRUE: {
setBeaconState(BEACON_ZONE_IN);
Toast.makeText(BeaconFenceActivity.this, "You've entered the beacon zone!", Toast.LENGTH_SHORT).show();
Log.e("Beacon", "In Range");
break;
}
case FenceState.FALSE: {
setBeaconState(BEACON_ZONE_OUT);
Log.e("Beacon", "Out of Range");
Toast.makeText(BeaconFenceActivity.this, "You've Out of beacon Range!", Toast.LENGTH_SHORT).show();
break;
}
case FenceState.UNKNOWN: {
setBeaconState(FenceState.UNKNOWN);
Log.e("Beacon", "UNKNOWN");
Toast.makeText(BeaconFenceActivity.this, "Oops, Beacon status is unknown!", Toast.LENGTH_SHORT).show();
break;
}
}
}
}
}
private void setBeaconState(int beaconState) {
if (beaconState == BEACON_ZONE_IN) {
txtBeacon.setText("You've entered the beacon zone!");
} else if (beaconState == BEACON_ZONE_OUT) {
txtBeacon.setText("You're not in the beacon zone..");
} else {
txtBeacon.setText("Oops, Beacon status is unknown!");
}
}
}
I Hope you can understand my question.
Thank you.
I can't tell you why it is taking to much time.
But in case of the accuracy you have to keep in mind,
that your position to the beacons is calculated from
the signal/signalstrength that beacons send and like every signal in
the microwave spectrum it gets reflected, blocked etc.
The environment in which you use your beacons could be
far from ideal to get the accuracy you want with the information
provided by the beacons.

ProgressDialog not updating after Configuration Change (orientation turns to horizontal)

ProgressDialog quits updating when orientation of screen changes. I have put into place a fix that salvages the asynctask and sets the activity of the asynctask to the new activity after it is destroyed and rebuilt. The percentage complete on the progressdialog stays at the percentage it was at before the orientation change.
What am I missing?
package net.daleroy.fungifieldguide.activities;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Toast;
import net.daleroy.fungifieldguide.R;
import net.daleroy.fungifieldguide.fungifieldguideapplication;
public class FungiFieldGuide extends Activity {
//static final int PROGRESS_DIALOG = 0;
//ProgressThread progressThread;
private final static String LOG_TAG = FungiFieldGuide.class.getSimpleName();
fungifieldguideapplication appState;
private DownloadFile mTask;
public boolean mShownDialog;
ProgressDialog progressDialog;
private final static int DIALOG_ID = 1;
#Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
if ( id == DIALOG_ID ) {
mShownDialog = true;
}
}
private void onTaskCompleted() {
Log.i(LOG_TAG, "Activity " + this + " has been notified the task is complete.");
//Check added because dismissDialog throws an exception if the current
//activity hasn't shown it. This Happens if task finishes early enough
//before an orientation change that the dialog is already gone when
//the previous activity bundles up the dialogs to reshow.
if ( mShownDialog ) {
dismissDialog(DIALOG_ID);
Toast.makeText(this, "Finished..", Toast.LENGTH_LONG).show();
}
}
#Override
protected Dialog onCreateDialog(int id) {
switch(id) {
case DIALOG_ID:
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading Database (only first run)...");
return progressDialog;
default:
return super.onCreateDialog(id);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
appState = ((fungifieldguideapplication)this.getApplication());
Object retained = getLastNonConfigurationInstance();
if ( retained instanceof DownloadFile ) {
Log.i(LOG_TAG, "Reclaiming previous background task.");
mTask = (DownloadFile) retained;
mTask.setActivity(this);
//showDialog(DIALOG_ID);
}
else {
if(!appState.service.createDataBase())
{
Log.i(LOG_TAG, "Creating new background task.");
//showDialog(DIALOG_ID);
mTask = new DownloadFile(this);
mTask.execute("http://www.codemarshall.com/Home/Download");
}
}
//showDialog(PROGRESS_DIALOG);
View btn_Catalog = findViewById(R.id.btn_Catalog);
btn_Catalog.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Intent i = new Intent(getBaseContext(), Cat_Genus.class);//new Intent(this, Total.class);
startActivity(i);
}
});
View btn_Search = findViewById(R.id.btn_Search);
btn_Search.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Intent i = new Intent(getBaseContext(), Search.class);//new Intent(this, Total.class);
startActivity(i);
}
});
}
#Override
public Object onRetainNonConfigurationInstance() {
mTask.setActivity(null);
return mTask;
}
#Override
public void onDestroy()
{
super.onDestroy();
//progressDialog.dismiss();
//progressDialog = null;
appState.service.ClearSearchParameters();
}
private class DownloadFile extends AsyncTask<String, Integer, Boolean>{
private FungiFieldGuide activity;
private boolean completed;
private String Error = null;
private String Content;
private DownloadFile(FungiFieldGuide activity) {
this.activity = activity;
}
#Override
protected void onPreExecute()
{
showDialog(DIALOG_ID);
}
#Override
protected Boolean doInBackground(String... urlarg) {
int count;
try {
URL url = new URL(urlarg[0]);
URLConnection conexion = url.openConnection();
conexion.setDoInput(true);
conexion.setUseCaches(false);
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// downlod the file
InputStream input = new BufferedInputStream(conexion.getInputStream());
OutputStream output = new FileOutputStream("/data/data/net.daleroy.fungifieldguide/databases/Mushrooms.db");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int)total*100/lenghtOfFile);
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
Log.i(LOG_TAG, e.getMessage());
}
return null;
}
#Override
public void onProgressUpdate(Integer... args){
progressDialog.setProgress(args[0]);
}
#Override
protected void onPostExecute(Boolean result)
{
completed = true;
notifyActivityTaskCompleted();
}
private void notifyActivityTaskCompleted() {
if ( null != activity ) {
activity.onTaskCompleted();
}
}
private void setActivity(FungiFieldGuide activity) {
this.activity = activity;
if ( completed ) {
notifyActivityTaskCompleted();
}
}
}
}
This is not a real solution but to prevent this I just disabled orientation changes during the life of the AsyncTask with adding first:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
and when the job is done:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
Hope this helps.

Categories