starting activity from a callback method - java

i use a class WebServiceAdapter using volley library for implementing http connections. since i can't find a way to return a string to activity
i use an interface to callnback into MainActivity. in it i want to start a new activity but it is not starting
my WebServiceAdapterClass
public WebServiceAdapter(Context context){
this.context = context;
status = "new";
rQueue = Volley.newRequestQueue(context);
}
private WebServiceInterface wsi;
public void sendGetRequest(String page,Map<String,String> map, WebServiceInterface i){
wsi = i;
String query = "";
if(!map.isEmpty()){
for (Map.Entry<String, String> entry : map.entrySet())
{
query =query + entry.getKey()+"="+entry.getValue()+'&';
}
}
if(query.length() != 0)
query = query.substring(0,query.length()-1);
StringRequest sRequest = new StringRequest(Request.Method.GET,BASE_URI+page+"?"+query,
new Response.Listener<String>() {
#Override
public void onResponse(String response){
wsi.successCallback(response,context);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error){
wsi.errorCallback("failed",context);
}
});
rQueue.add(sRequest);
}
and in MainActivity inside callBack which use an interface for callback
#Override
public void successCallback(String s, Context c) {
Intent myintent = new Intent(c,VerifyRegister.class);
startActivity(myintent);
finish();
}
but the activity is not starting
i tried passing this , getApplicationContext() and Main Activity.this instead of c. but never worked
what i wanted was return a string on success i cant find another way
but the new activity is not starting
update
code of verifyRegister class
public class VerifyRegister extends Activity implements WebServiceInterface{
private Button verifyButton;
private EditText loginVerify;
StorageAdapter sAdapter;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
sAdapter = new StorageAdapter();
if(sAdapter.getValue(this, "phone").length() == 0)
finish();
setContentView(R.layout.login_verify);
verifyButton = (Button) findViewById(R.id.verifyButton);
loginVerify = (EditText) findViewById(R.id.loginVerify);
verifyButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
}
});
}
#Override
public void successCallback(String s, Context c) {
// TODO Auto-generated method stub
}
#Override
public void errorCallback(String s, Context c) {
// TODO Auto-generated method stub
}
*update 2 *
i called the WebService Adapter like this
wAdaptor = new WebServiceAdapter(this);
wAdaptor.sendGetRequest("/register",new HashMap<String,String> (),this);

Please verify that your VerifyRegister class does in fact extends Activity. And if it does extends, please make sure that you have added it in AndroidManifest file.
One more thing you can try is, you can write it like this:
Intent myintent = new Intent(MainActivity.this,VerifyRegister.class);

Try this:
#Override
public void successCallback(String s, Context c) {
Intent myintent = new Intent(MainActivity.this,VerifyRegister.class);
c.startActivity(myintent);
//finish(); Dont use this
}

New activity starts with Context, I your case you should call it by using to activity currently running.
MainActivity.this.startActivity(anyintent);

i searched similar projects in github
and found this
public void successCallback(String s, Context c) {
Intent myintent = new Intent(MainActivity.this,VerifyRegister.class);
MainActivity.this.startActivity(myintent);
finish()
}

Related

Flag from AsyncTask class doesn't work properly in main class

I've created some lines of code which are supposed to switch to the next activity if connection is set without any exceptions. But if there are some exceptions, it should make "Error!" toast and not go to the next activity.
Boolean flag in Connection class works well: if the server is off, app will say "Error!", if on, it won't. But same flag in main class (con.flag) doesn't work properly, it looks like it is always false. App always switches to the next activity, with making toast or without, depending on server status. What's wrong in my code? I suppose that there's something I don't know about AsyncTask classes' fields initialization.
So, here is my code:
public class Connection extends AsyncTask<Void, Void, String> {
Context mContext;
public Connection(Context context){
this.mContext = context;
}
static String value;
boolean flag = false;
#Override
protected String doInBackground(Void... arg0) {
try {
Jedis jedis = new Jedis("192.168.0.120", 6381);
String name = jedis.ping();
value = name;
} catch (Exception e){
flag = true;
}
return null;
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (flag) {
Toast toast = Toast.makeText(mContext,
"Error!", Toast.LENGTH_LONG);
toast.show();
}
}
}
public class MainActivity extends AppCompatActivity {
Button click;
Context maincontext = this;
public void goTo2ndActivity(){
Intent intent = new Intent(this, Main2Activity.class);
startActivity(intent);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
click = (Button)findViewById(R.id.button);
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Connection con = new Connection(maincontext);
con.execute();
if (!con.flag){
goTo2ndActivity();
}
}
});
}
}
Your problem seems to be a race condition between main thread and the asynctask, the problem is in the onClick listener:
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final Connection con = new Connection(maincontext);
con.execute();
if (!con.flag){
goTo2ndActivity();
}
}
});
so this part
if (!con.flag){
goTo2ndActivity();
}
must be called from on post execute of your async task, for that pass the activity to the constructor of the async task like this:
update constructor of async task:
public class Connection extends AsyncTask<Void, Void, String> {
Context mContext;
MainActivity activity;
public Connection(Context context,MainActivity activity){
this.mContext = context;
this.activity= activity
}
..........
..........
and on post execute:
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (flag) {
Toast toast = Toast.makeText(mContext,
"Error!", Toast.LENGTH_LONG);
toast.show();
}else{
//go to next activity
activity.goTo2ndActivity();
}
}
now your button click becomes:
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//just execute
final Connection con = new Connection(maincontext,this);
con.execute();
}
});

Android use Broadcast Receivers to send value

I have this AccessibilityService class:
public class USSDService extends AccessibilityService {
public static String TAG = "USSDService";
public String responsee="";
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.d(TAG, "onAccessibilityEvent");
String text = event.getText().toString();
if (event.getClassName().equals("android.app.AlertDialog")) {
performGlobalAction(GLOBAL_ACTION_BACK);
Log.d(TAG, text);
Intent intent = new Intent("message");
intent.putExtra("value", text);
Toast.makeText (this,text,Toast.LENGTH_LONG).show();
this.sendBroadcast(intent);// write a broad cast receiver and call sendbroadcast() from here, if you want to parse the message for balance, date
}
}
#Override
public void onInterrupt() {
}
#Override
protected void onServiceConnected() {
super.onServiceConnected();
Log.d(TAG, "onServiceConnected");
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.flags = AccessibilityServiceInfo.DEFAULT;
info.packageNames = new String[]{"com.android.phone"};
info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
setServiceInfo(info);
}}
As you can see in the method onAccessibilityEvent, I send intent by using the method sendBroadcast.
In MainActivity I use BroadcastReceiver to receive the value like this:
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver bReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
//put here whaterver you want your activity to do with the intent received
Log.i("onReceive",intent.getStringExtra("value") );
}
};
protected void onResume(){
super.onResume();
Log.i("onResume", "22222");
LocalBroadcastManager.getInstance(this).registerReceiver(bReceiver, new IntentFilter("message"));
}
protected void onPause (){
super.onPause();
Log.i("onPause", "11111");
LocalBroadcastManager.getInstance(this).unregisterReceiver(bReceiver);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);}}
My App works fine when I call ussd the method onAccessibilityEvent is work and the value show in Toast, but the method onReceive did not work and I don't know where the problem is. Please help me.
An AccessibilityService that has been launched properly and your Activity are going to exist in separate processes. This is by definition. Assuming that you have launched your AccessibilityService properly, the following is what you want.
public class USSDService extends AccessibilityService {
public void onAccessibilityEvent(AccessibilityEvent event) {
Intent intent = new Intent(getPackageName() + "ACTION_ID");
intent.putExtra("extra_id", "value");
sendBroadcast(intent);
}
}
You would then register for this broadcast in your Activity like so:
public class MainActivity extends AppCompatActivity {
protected void onResume(){
super.onResume();
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("Broadcast", intent.getExtras().getString("extra_id"));
}
}, new IntentFilter(getPackageName() + "ACTION_ID"));
}
}
Important part here is A: your intent filter is tied to your package name, and that "ACTION_ID" is always the same string. Ultimately this is probably best accomplished by a public static final string in either your Activity class or your service class... or in some other class abstracting away this layer of communication.

how to control the Activity method flow till non activity class perform network operation

i have one method in activity in which some operations are performed from non activity class. i want to know when the non activity class network operation are completed so that i can call that method again. but when i call non activity class then the method goes to at the end.
here is my code
public void somemethod(){
.
.
.
.
if (condition) {
new RegenerateToken().generate(DriverActivity.this); // calling non activity class which perform some network operation
//here i want to know that non activity class has performed the network operation so i can call this method again
}
.
.
.
log.d("method","ending");
}
non activity class
public class RegenerateToken {
public void generate(Context context) {
ExecuteServerReq executeServerReq = new ExecuteServerReq(context, client, Utilz.URL + "/authenticate", params, true, true);
executeServerReq.execute();
executeServerReq.getResponse = new ExecuteServerReq.GetResponse() {
#Override
public void onResponse(String objects) {
Utilz.printLog("RegenerateTokenresponse", objects);
}
};
}
}
You need to implement an interface to get the callback
public class RegenerateToken {
public interface Callback {
public void onResponce(String data);
}
public void generate(Context context,final Callback callBack) {
ExecuteServerReq executeServerReq = new ExecuteServerReq(context, client, Utilz.URL + "/authenticate", params, true, true);
executeServerReq.execute();
executeServerReq.getResponse = new ExecuteServerReq.GetResponse() {
#Override
public void onResponse(String objects) {
Utilz.printLog("RegenerateTokenresponse", objects);
callBack.onResponce(objects);
}};
}
}
Callback implementation
if(condition) {
new RegenerateToken().generate(DriverActivity.this, new Callback() {
#Override
public void onResponse(String objects) { //your data do ur processing
}
});
}
You can use LocalBroacastManager to send and receive information within your app
public class RegenerateToken {
public void generate(Context context) {
//your code
executeServerReq.getResponse = new ExecuteServerReq.GetResponse() {
#Override
public void onResponse(String objects) {
Utilz.printLog("RegenerateTokenresponse", objects);
Intent intent = new Intent("Respone");
if(expected responce){
intent.putExtra("result", "Successful");
}
else{
intent.putExtra("result", "UnSuccessful");
}
LocalBroadcastManager.getInstance(this).sendBroadcast(iIntent);
}
};
}
}
And at your Activity register and define a receiver for your Local Broadcast
#Override
public void onCreate(Bundle savedInstanceState) {
...
//Register the custom Broadcast "Response"
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("Response"));
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "Response" is broadcasted.
private BroadcastReceiver myMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String response= intent.getStringExtra("result");
if(response.equals("Successful")){
//on successful execution
// call your method again or do whatever you wish
}else{
//on otherwise
}
}
};

Calling notifyOnDataSetChanged in AsyncTask (not within the class)

*************PROBLEM FIXED, CHECK BELOW FOR A SOLUTION*************
I have been struggling with that nearly half a day. Cannot get it work properly.
I have AsyncTask with private method, so I can pass boolean and String values in CustomLvAdapter
private void changeJobStatus(final boolean isAppliedforAJob, final String jobID){
class ChangeJobStatus extends AsyncTask<Void,Void,String> {
//private Delegates del = null;
ProgressDialog loading;
#Override
protected void onPreExecute() {
super.onPreExecute();
if(isAppliedforAJob) {
loading = ProgressDialog.show(context, "","Canceling application", false);
}
else {
loading = ProgressDialog.show(context, "","Applying for position", false);
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//del.asyncCompleteOnCustomJob(true);
loading.dismiss();
}
#Override
protected String doInBackground(Void... v) {
String res;
HashMap<String,String> params = new HashMap<>();
params.put(Config.KEY_USER_ID, studentID);
params.put(Config.KEY_JOB_ID, jobID);
RequestHandler rh = new RequestHandler();
if(isAppliedforAJob)
res = rh.sendPostRequest(Config.URL_CANCEL_APPLICATION, params);
else
res = rh.sendPostRequest(Config.URL_APPLY_FOR_A_JOB, params);
Log.d("Stringas", "CustomListViewBackground " + res);
return res;
}
}
ChangeJobStatus cjs = new ChangeJobStatus();
cjs.execute();
}
and in onPostExcecute() I want to call notifyOnDataSetChanged() to my another activity lvAdapters.
As far as I read I have to implement delegate interface, but I didnt succeed doing that. I fail at initializing delegate in my main class, because changeJobStatus method is private and it is called in customLvAdapter class.
If I make a constructor in ChangeJobStatus class
public ChangeJobStatus(Delegates delegate)
{
this.del = delegate;
}
I have to pass something in the parameters, when excecuting it. If I pass new Delegate, my delegate implementation, which is in my another activity is not triggered.
ChangeJobStatus cjs = new ChangeJobStatus(new Delegates() {
#Override
public void asyncCompleteOnCustomJob(boolean success) {
//whatever
}
});
cjs.execute();
I hope you can help me figure out right implementation for that,
Cheers
***********SOLUTION***********
Sadly, I couldn't implement what fellow user gave to me, but I am very glad that I heard from one of you I can use broadcast receiver. And it worked.
This is what I did
Create a Broadcast Receiver in your main class
private final BroadcastReceiver broadcastJobList = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//what will happen, when event triggers
}
};
Register custom intent and register it to Broadcast receiver in your main class onCreate method or wherever you feel comfortable :)
IntentFilter filter = new IntentFilter();
filter.addAction("jobListChanged");
registerReceiver(broadcastJobList, filter);
All we left to do is send intent which will trigger Broadcast receiver. Following code in my scenario went to onPostExcecute method in custom adapter (context was initialized for Context at the beggining of custom adapter)
Intent intent = new Intent();
intent.setAction("jobListChanged");
context.sendBroadcast(intent);
Hope I will help anyone that has this problem. Cheers!
// your asynctask class
public class ChangeJobStatus extends AsyncTask<String, Void, String> {
private ProgressDialog loading;
private OnResponseListener responseListener;
private boolean isAppliedforAJob;
private Context con;
public ChangeJobStatus(Context con,boolean state) {
super();
// TODO Auto-generated constructor stub
this.con=con;
isAppliedforAJob = state;
}
public void setOnResponseListener(OnResponseListener onLoadMoreListener) {
this.responseListener = onLoadMoreListener;
}
public interface OnResponseListener {
public void onResponse(String responsecode);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
if (isAppliedforAJob) {
loading = ProgressDialog.show(con, "", "Canceling application", false);
} else {
loading = ProgressDialog.show(con, "", "Applying for position", false);
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// del.asyncCompleteOnCustomJob(true);
loading.dismiss();
responseListener.onResponse(s);
}
#Override
protected String doInBackground(String... param) {
String res="";
HashMap<String, String> params = new HashMap<>();
params.put(Config.KEY_JOB_ID, param[0]);// job id
params.put(Config.KEY_USER_ID, param[1]);// student id
RequestHandler rh = new RequestHandler();
if (isAppliedforAJob)
res = rh.sendPostRequest(Config.URL_CANCEL_APPLICATION, params);
else
res = rh.sendPostRequest(Config.URL_APPLY_FOR_A_JOB, params);
return res;
}
}
in your activity class
public class MainActivity extends Activity implements OnResponseListener {
String jobId="1",studId="1";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ChangeJobStatus cbs=new ChangeJobStatus(this, true);
cbs.setOnResponseListener(this);
cbs.execute(jobId,studId);
}
#Override
public void onResponse(String responsecode) {
// TODO Auto-generated method stub
//here u can do ur stuff with the string
}
}

MQTT Implementation Issue (Dale Lane Example)

I am running into an issue with the implementation of the Dale Lane MQTT solution.
I cannot seem to figure out how to retrieve the published message from the MQTT Client I am using.
I am not sure if I am utilizing the the onReceive() method incorrectly, but for now all I would like to do is log the broadcasted messages.
http://dalelane.co.uk/blog/?p=1599
The service I have implemented is exactly as listed here, I have no errors.
public class MQTTNotifier extends Activity implements OnClickListener {
String preferenceBrokerHost, preferenceBrokerTopic;
private StatusUpdateReceiver statusUpdateIntentReceiver;
private MQTTMessageReceiver messageIntentReceiver;
private EditText etBroker, etTopic;
Button btnSubscribe, btnStopService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mqttnotifier);
initValues();
// startService();
}
private void initValues() {
btnSubscribe = (Button) findViewById(R.id.btnSubscribe);
btnSubscribe.setOnClickListener(this);
btnStopService = (Button) findViewById(R.id.btnStopService);
btnStopService.setOnClickListener(this);
// if statement to see if sharedpreferences exist, if so reopen recievers
/*
* statusUpdateIntentReceiver = new StatusUpdateReceiver(); IntentFilter intentSFilter = new
* IntentFilter(MQTTService.MQTT_STATUS_INTENT); registerReceiver(statusUpdateIntentReceiver,
* intentSFilter);
*
* messageIntentReceiver = new MQTTMessageReceiver(); IntentFilter intentCFilter = new
* IntentFilter(MQTTService.MQTT_MSG_RECEIVED_INTENT); registerReceiver(messageIntentReceiver,
* intentCFilter);
*/
}
public class StatusUpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle notificationData = intent.getExtras();
String newStatus = notificationData.getString(MQTTService.MQTT_STATUS_MSG);
}
}
public class MQTTMessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle notificationData = intent.getExtras();
String newTopic = notificationData.getString(MQTTService.MQTT_MSG_RECEIVED_TOPIC);
String newData = notificationData.getString(MQTTService.MQTT_MSG_RECEIVED_MSG);
Log.e("NEW TOPIC", newTopic);
Log.e("NEW DATA", newData);
}
}
#Override
protected void onDestroy() {
unregisterReceiver(statusUpdateIntentReceiver);
unregisterReceiver(messageIntentReceiver);
}
private void startService() {
Intent svc = new Intent(this, MQTTService.class);
startService(svc);
}
private void stopService() {
Intent svc = new Intent(this, MQTTService.class);
stopService(svc);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.cancel(MQTTService.MQTT_NOTIFICATION_UPDATE);
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btnSubscribe:
etBroker = (EditText) findViewById(R.id.etBroker);
etTopic = (EditText) findViewById(R.id.etTopic);
preferenceBrokerHost = etBroker.getText().toString().trim();
preferenceBrokerTopic = etBroker.getText().toString().trim();
createSharedPreferences(preferenceBrokerHost, preferenceBrokerTopic);
establishRecievers();
startService();
break;
case R.id.btnStopService:
stopService();
}
}
private void createSharedPreferences(String broker, String topic) {
SharedPreferences settings = getSharedPreferences(MQTTService.APP_ID, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("broker", broker);
editor.putString("topic", topic);
editor.commit();
}
private void establishRecievers() {
statusUpdateIntentReceiver = new StatusUpdateReceiver();
IntentFilter intentSFilter = new IntentFilter(MQTTService.MQTT_STATUS_INTENT);
registerReceiver(statusUpdateIntentReceiver, intentSFilter);
messageIntentReceiver = new MQTTMessageReceiver();
IntentFilter intentCFilter = new IntentFilter(MQTTService.MQTT_MSG_RECEIVED_INTENT);
registerReceiver(messageIntentReceiver, intentCFilter);
}
}
It turns out that the issue was in regards to a simple mistake that was in regards to this line.
preferenceBrokerTopic = etBroker.getText().toString().trim();
I corrected the issue and now it corrects properly because it was not subscribing to the correct topic.
preferenceBrokerTopic = etTopic.getText().toString().trim();

Categories

Resources