public class BackgroundTasker extends AsyncTask {
int progress;
#Override
protected void onPreExecute() {
result.startAnimation(fadeIn);
result.setTextSize(32);
progressupdator(20);
result.setText("Starting...");
}
#Override
protected Long[] doInBackground(String... address) {
while (true) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(new Long[] {
MainActivity.this.getvalue(address[0]) });
}
}
protected void onProgressUpdate(Long... values){
if(values[0]==Long.valueOf(333)) {
setProgress(100);
result.setText("N/A");
builder.setContentText("N/A");
notificationManager.notify(1,builder.build());
}
else{
setProgress(100);
result.setText(String.valueOf(values[0])+"ms");
builder.setContentText(String.valueOf(values[0])+"ms");
notificationManager.notify(1,builder.build());
}
}
protected void onPostExecute(int d) {
}
#Override
public void onClick(View v) {
DatabaseReference myRef = database.getReference("message");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
BackgroundTasker r = new BackgroundTasker();
r.execute(dataSnapshot.getValue(String.class));
Log.d("Fireabse", "Value is: " + value);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("Firebase", "Failed to read value.", error.toException());
}
});
}
});
I want that whenever the button connected to onClick is pressed, The r.execute take new values from Firebase Realtime Database and perform AsyncTask with the new values.
How do i do that?
Related
I am building an app that should connect at least 4 devices using nearby connection api. I am able to connect them intermittently, other wise only two devices are getting connected.
I am using P2P-CLUSTER Topology and sending data as file payloads which are successfully sent.
I have two questions:
Any suggestion on how to have a stable connection among 2+ devices.
While sending data as file payloads, a folder is created in the download folder. Is there any way to discard this step and be able to send data directly as file payloads without having to save them locally.
Here is my code regarding the connection part only.
private final EndpointDiscoveryCallback endpointDiscoveryCallback =
new EndpointDiscoveryCallback() {
#Override
public void onEndpointFound(String endpointId, final DiscoveredEndpointInfo info) {
arrlist.add(endpointId);
for (int i = 0; i< arrlist.size(); i++) {
connectionsClient
.requestConnection(Build.MODEL, arrlist.get(i), connectionLifecycleCallback)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
}
}
#Override
public void onEndpointLost(#NonNull String endpointId) {
}
};
private final ConnectionLifecycleCallback connectionLifecycleCallback =
new ConnectionLifecycleCallback() {
#Override
public void onConnectionInitiated(#NonNull String endpointId, #NonNull ConnectionInfo connectionInfo) {
// Automatically accept the connection on both sides.
connectionsClient.acceptConnection(endpointId, new PayloadCallback() {
#Override
public void onPayloadReceived(#NonNull String s, #NonNull Payload payload) {
}
}
#Override
public void onPayloadTransferUpdate(#NonNull String s, #NonNull PayloadTransferUpdate payloadTransferUpdate) {
}
#Override
public void onConnectionResult(#NonNull String endpointId, ConnectionResolution result) {
switch (result.getStatus().getStatusCode()) {
case ConnectionsStatusCodes.STATUS_OK:
if(arrlist != null && arrlist.contains(endpointId)){
System.out.println(TAG+ " End Point Found");
} else {
arrlist.add(endpointId);
}
connectionsClient.stopDiscovery();
connectionsClient.stopAdvertising();
break;
case ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED:
// Some code
break;
case ConnectionsStatusCodes.STATUS_ERROR:
// Some code
break;
default:
}
}
#Override
public void onDisconnected(#NonNull String endpointId) {
// some code
}
};
private void startAdvertising() {
AdvertisingOptions advertisingOptions =
new AdvertisingOptions.Builder().setStrategy(STRATEGY).build();
Nearby.getConnectionsClient(context)
.startAdvertising(
android.os.Build.MODEL, getPackageName(), connectionLifecycleCallback, advertisingOptions)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
}
private void startDiscovery() {
DiscoveryOptions discoveryOptions =
new DiscoveryOptions.Builder().setStrategy(STRATEGY).build();
Nearby.getConnectionsClient(context)
.startDiscovery(getPackageName(), endpointDiscoveryCallback, discoveryOptions)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
}
In my App i have added Observable method in menuitemclicked but it's working when i'm clicking it twice . on Single press. method is not working but button is working fine any suggestion for this or any changes in method .
case R.id.upload:
fetch()
break;
io.reactivex.Observable fetchObservable() {
return io.reactivex.Observable.create(new ObservableOnSubscribe<Data>() {
#Override
public void subscribe(ObservableEmitter<Data> emitter) throws Exception {
try {
final Cursor cursor = getActivity().getContentResolver().query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{"display_name", "data1"}, null, null, null);
// final Map contact =new HashMap();
while (cursor.moveToNext()) {
Data data = new Data();
try {
String name = cursor.getString(cursor.getColumnIndex(Display_name));
String number = cursor.getString(cursor.getColumnIndex(Data1));
data.setContact_name(name);
data.setNumber(number);
Thread.sleep(60);
emitter.onNext(data);
} catch (Exception e) {
Toast.makeText(context, "not insert , Toast.LENGTH_SHORT).show();
}
}
emitter.onComplete();
}catch (Exception e){
emitter.onError(e);
}
}
});
// fetching method code
void fetch(){
fetchObservable().subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(Data data) {
data.Contact_name=data.getContact_name();
data.number=data.getNumber();
String name= data.Contact_name;
String number= data.number;
}
count++;
textprogress.setText(String.valueOf(count));
}
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});
}
Because u are not Running your UI in main thread
like this
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
textprogress.setVisibility(View.VISIBLE);
textprogress.setVisibility(View.VISIBLE);
}
});
I have a Firebase listener that checks if User exists (Im making login/signup using Firebase database) in order to tell if the username is taken or not, the problem is that it takes 2 clicks on the Signup button for it to work, because the listener cant tell if username exists or not fast enough, only on second click when it already decided for the first click it is possible to signup, but then again it does not really check the username of the second click (If I change username now, even if it is taken it will work)
database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Users/" + usernameEt.getText().toString() +"/password");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
if(value != null) {
Toast.makeText(getApplicationContext(), "Username Taken", Toast.LENGTH_SHORT).show();
clear = false;
}else
clear = true;
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
clear = false;
Toast.makeText(getApplicationContext(), "Internet Error", Toast.LENGTH_SHORT).show();
}
});
//insert check if clear has value
if(!clear) //TODO FIX takes time to the listener to do the job
return false;
clear is a Boolean type var and is null at the first time this code runs, this code is for checking if username is taken or not
Maybe your code looks like this:
#Override
public void onCreate(Bundle savedInstanceState) {
...
signUpBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (checkUserExists()) {
...
} else {
signUp();
}
}
}
}
private boolean checkUserExists() {
database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Users/" + usernameEt.getText().toString() +"/password");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
if(value != null) {
Toast.makeText(getApplicationContext(), "Username Taken", Toast.LENGTH_SHORT).show();
clear = false;
}else
clear = true;
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
clear = false;
Toast.makeText(getApplicationContext(), "Internet Error", Toast.LENGTH_SHORT).show();
}
});
//insert check if clear has value
if(!clear) //TODO FIX takes time to the listener to do the job
return false;
}
private void signUp() {
...
}
You should change it to:
#Override
public void onCreate(Bundle savedInstanceState) {
...
signUpBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
checkUserExists();
}
}
}
private boolean checkUserExists() {
database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Users/" + usernameEt.getText().toString() +"/password");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String value = dataSnapshot.getValue(String.class);
if(value != null) {
Toast.makeText(getApplicationContext(), "Username Taken", Toast.LENGTH_SHORT).show();
} else {
signUp(); // sign up here
}
}
#Override
public void onCancelled(DatabaseError error) {
Toast.makeText(getApplicationContext(), "Internet Error", Toast.LENGTH_SHORT).show();
}
});
}
private void signUp() {
...
}
Also you can block user input while checking user data:
private boolean checking = false; // added
#Override
public void onCreate(Bundle savedInstanceState) {
...
signUpBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (checking) return; // added
checkUserExists();
checking = true; // added
}
}
}
private boolean checkUserExists() {
database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Users/" + usernameEt.getText().toString() +"/password");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
checking = false; // added
String value = dataSnapshot.getValue(String.class);
if(value != null) {
Toast.makeText(getApplicationContext(), "Username Taken", Toast.LENGTH_SHORT).show();
} else {
signUp(); // sign up here
}
}
#Override
public void onCancelled(DatabaseError error) {
checking = false; // added
Toast.makeText(getApplicationContext(), "Internet Error", Toast.LENGTH_SHORT).show();
}
});
}
private void signUp() {
...
}
Hope it works.
I need to save in Realm a JSON that I've saved in Assets folder.
So I've decided to do it in this way:
private void putCountryIntoRealm()
{
Observable.create(new Observable.OnSubscribe<String>()
{
public void call(Subscriber<? super String> subscriber)
{
try
{
InputStream is = getActivity().getAssets().open("countries.json");
Reader inRead = new InputStreamReader(is);
Gson gson = new Gson();
JsonReader reader = new JsonReader(inRead);
reader.setLenient(true);
reader.beginArray();
while (reader.hasNext())
{
CountryObject ct = gson.fromJson(reader, CountryObject.class);
country.add(ct);
System.out.println("size ct: "+country.size());
subscriber.onNext(reader.toString());
}
reader.endArray();
reader.close();
subscriber.onCompleted();
}
catch (IOException e)
{
subscriber.onError(e);
}
}
}).subscribeOn(Schedulers.newThread())
.subscribe(new Subscriber<String>()
{
#Override
public void onCompleted()
{
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run()
{
realm.executeTransactionAsync(new Realm.Transaction()
{
float total = 0;
float size = country.size();
String progressCount;
public void execute(Realm mRealm)
{
Countries countries = new Countries();
int i;
System.out.print("countries size: "+size);
for (i = 0; i < country.size(); i++)
{
total = (i/size * 100);
progressCount = String.format("%.0f",total);
countries.setId(country.get(i).getId());
countries.setCode(country.get(i).getCode());
countries.setName(country.get(i).getName());
countries.setContinent(country.get(i).getContinent());
countries.setKeywords(country.get(i).getKeywords());
countries.setWikipedia_link(country.get(i).getWikiLink());
mRealm.insertOrUpdate(countries);
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run()
{
//Log.d("%",progressCount);
dialog = new ProgressDialog(getActivity());
dialog.setTitle("Salvataggio country in corso");
dialog.setMessage(progressCount+"%");
}
});
}
}
},new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess()
{
Log.wtf("va","Ok");
if(dialog.isShowing())
dialog.dismiss();
}
}, new Realm.Transaction.OnError()
{
#Override
public void onError(Throwable error)
{
error.printStackTrace();
}
});
}
});
}
#Override
public void onError(Throwable e)
{
e.printStackTrace();
}
#Override
public void onNext(String s)
{
System.out.println(s);
}
});
}
but I have this error:
W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'long com.plenitudesrls.aviocalc.helpful.CountryObject.getId()' on a null object reference
In fact, I print logs and the size in onNext() is 245, in onCompleted() is null.
Why I have this error? I have another case where this works good.
Thanks
EDIT: it works good, the problem was a MalformedJson that cause the crash
I've this code:
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(GithubService.SERVICE_ENDPOINT).build();
GithubService service = retrofit.create(GithubService.class);
service.getAirport()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Airport>>() {
List<Airport> airps = new ArrayList<Airport>();
#Override
public void onCompleted() {
for(final Airport air : airps) {
realm.executeTransactionAsync(new Realm.Transaction() {
#Override
public void execute(Realm mRealm) {
AirportR airport = mRealm.createObject(AirportR.class);
airport.setId(air.getId());
}
}, new Realm.Transaction.OnSuccess() {
#Override
public void onSuccess() {
Log.wtf("ok", "ok");
}
}, new Realm.Transaction.OnError() {
#Override
public void onError(Throwable error) {
Log.e("ok", "non vaaa");
}
});
}
}
#Override
public void onError(Throwable e) {
e.printStackTrace();
}
#Override
public void onNext(List<Airport> airports) {
airps = airports;
}
});
}
});
and I need to put a download percentage because airports are so much..and so I want to put in a textview the percentage of the download (and I don't know how to do it in onNext() method) and the percentage of the realm adding in the airport...
It's possible to do?
Thanks
I used this function to show download progress, combine by rxjava and okhttp, hope it helps.
private void initOkHttpClient() {
mOkHttpClient = new OkHttpClient();
mRequest = new Request.Builder().url(URL_JSON).build();
}
private void rxPublishProgress() {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setMax(100);
mProgressDialog.setCancelable(true);
mProgressDialog.show();
mRequest = new Request.Builder().url(URL_IMAGE).build();
Observable.create(new Observable.OnSubscribe<String>() {
#Override
public void call(Subscriber<? super String> subscriber) {
try {
InputStream inputStream;
Response response = mOkHttpClient.newCall(mRequest).execute();
if (response.isSuccessful()) {
inputStream = response.body().byteStream();
long len = response.body().contentLength();
String progress = "0";
subscriber.onNext(progress);
byte[] data = new byte[1024];
long total = 0;
int count;
while ((count = inputStream.read(data)) != -1) {
total += count;
progress = String.valueOf(total * 100 / len);
subscriber.onNext(progress);
}
inputStream.close();
subscriber.onCompleted();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).subscribeOn(Schedulers.newThread()).subscribe(new Subscriber<String>() {
#Override
public void onCompleted() {
LogUtils.d("onCompleted");
mProgressDialog.dismiss();
}
#Override
public void onError(Throwable e) {
LogUtils.d(e.toString());
mProgressDialog.dismiss();
}
#Override
public void onNext(final String progress) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressDialog.setProgress(Integer.parseInt(progress));
}
});
}
});
}