I'm developing an app that should return some text to the app that started the intent.
But the app that starts the intent is a IME/soft Keyboard. So StartActivityForResult is not available because an IME is a service.
How can I achieve this?
What I got so far:
Keyboard:
final Intent intent = new Intent("com.example.helloworld.GETTEXT");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.putExtra("keyboard", true);
startActivity(intent);
Other App:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle extras = getIntent().getExtras();
if (extras == null){
return;
} else {
finish();
}
}
#Override
public void finish() {
Intent data = new Intent();
data.putExtra("test", "PASSED");
setResult(RESULT_OK, data);
super.finish();
}
You can use ResultReceiver.
Look at this example, it's pretty clear explains how it works.
You could use a ResultReceiver for this is think.
ResultReceiver lReceiver = new KeyboardResultReceiver(aListener);
final Intent intent = new Intent("com.example.helloworld.GETTEXT");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.putExtra(EXTRA_RESULT_RECIEVER, lReceiver);
intent.putExtra("keyboard", true);
startActivity(intent);
private static final class KeyboardResultReceiver extends ResultReceiver {
public FileUploadResultReceiver() {
}
#Override
protected void onReceiveResult(int aResultCode, Bundle aResultData) {
//Do your thing here you can also use the bundle for your data transmission
}
}
Related
I am working on an online radio app demo. I've created an error Activity which I want to take the user to, when an error occurs. In the error page, there is a refresh button, which is supposed to refresh the last Activity where an error occurred. But I don't know how to get the Intent of previous Activity which led to the error page to get it refresh on ButtonClick, I only know to make it return to a particular Activity.
You can use startActivityForResult in both calling activities
In MainActivity.java
int REFRESH = 1;
private void startErrorActivity() {
startActivityForResult(new Intent(this, ErrorActivity.class), REFRESH);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REFRESH) {
//do refresh
}
}
And in ErrorActivity.java
Button button = findViewById(R.id.refreshButton);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish(); //this will take you back to calling activities onActivityResult method
}
});
UPDATE:
I honestly think #sneharc's answer is better. Use that.
Try this:
public class ActivityA extends Activity {
public void myFunction(){
try{
// something bad happens here. need to go to ErrorActivity
}
catch (SomeException e){
Intent startErrorActivityIntent = new Intent(this, ErrorActivity.class);
startErrorActivityIntent.putExtra("sourceActivity", ActivityA.class.getSimpleName())
startActivity(this, startErrorActivityIntent)
}
}
}
public class ActivityB extends Activity {
public void myFunction(){
try{
// something bad happens here. need to go to ErrorActivity
}
catch (SomeException e){
Intent startErrorActivityIntent = new Intent(this, ErrorActivity.class);
startErrorActivityIntent.putExtra("sourceActivity", ActivityB.class.getSimpleName())
startActivity(this, startErrorActivityIntent)
}
}
}
public class ErrorActivity extends Activity {
private Intent mReceivedIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
mReceivedIntent = getIntent();
}
public void onClickRefresh(){
String retryActivityName = mReceivedIntent.getStringExtra("sourceActivity");
Intent retryActivityIntent = null;
if (!TextUtils.isEmpty(retryActivityName)){}
if (retryActivityName.equalsIgnoreCase(ActivityA.class.getSimpleName()))
retryActivityName = new Intent(this, ActivityA.class);
if (retryActivityName.equalsIgnoreCase(ActivityB.class.getSimpleName()))
retryActivityName = new Intent(this, ActivityB.class);
}
if (retryActivityIntent != null)
startActivityForResult(this, retryActivityIntent);
}
}
I am using an IntentService (for the first time), and I intend to return the result of this service by using a Bundle. However, when I do this, the main activity does not find the Bundle, returning null. What could cause this? The string keys match!
The code bellow outputs:
I/System.out: It's null
Main Activity:
public class MainMenu extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
//Some stuff here...
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(StorageHandler.TRANSACTION_DONE);
registerReceiver(broadcastReceiver, intentFilter);
Intent i = new Intent(this, StorageHandler.class);
startService(i);
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extra = getIntent().getBundleExtra("bundle");
if(extra == null){
System.out.println("It's null");
}
else {
ArrayList<String> objects = (ArrayList<String>) extra.getSerializable("objects");
System.out.println(objects.get(0));
}
}
};
}
IntentService:
public class StorageHandler extends IntentService{
public static final String TRANSACTION_DONE = "xx.xxxxx.xxxxxx.TRANSACTION_DONE";
public StorageHandler() {
super("StorageHandler");
}
public void onCreate(){
super.onCreate();
}
#Override
protected void onHandleIntent(Intent intent) {
notifyFinished();
}
private void notifyFinished(){
ArrayList<String> objects = new ArrayList<String>();
objects.add("Resulting Array here");
Bundle extra = new Bundle();
extra.putSerializable("objects", objects);
Intent i = new Intent();
i.setAction(xx.xxxxx.xxxxxx.StorageHandler.TRANSACTION_DONE);
i.putExtra("bundle", extra);
StorageHandler.this.sendBroadcast(i);
}
You're attempting to retrieve the data from the wrong Intent.
Change:
Bundle extra = getIntent().getBundleExtra("bundle");
To:
Bundle extra = intent.getBundleExtra("bundle");
The Intent that contains your data is supplied as one of the parameters of the BroadcastReceiver's onReceive() method.
you are using getIntent() to retrieve the broadcasted intent. This is wrong. The intent you have to use is the former paramter of onReceive. Change
Bundle extra = getIntent().getBundleExtra("bundle");
with
Bundle extra = intent.getBundleExtra("bundle");
Simply use this in your Activity:
In onResume callback you should register registerReceiver(broadcastReceiver, intentFilter);
And in onPause callback you should unregister this receiver. In your receiver use this:
Bundle extra = intent.getBundleExtra("bundle");
In your service use this code:
Intent i = new Intent(TRANSACTION_DONE).putExtra("bundle", extra);
this.sendBroadcast(i);
More information , see This Answer
Dont forget this in your onCreate MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//All your code here
}
I say this because I dont see that code line in your method!
Here is the code for back button. I want to kill other activities by back button but its not working in one activity, but I have other activities and without one activity its working fine. Please help me out.
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),
SomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
Might be this code will help you:
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), SomeActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
}
You have to set Flags according to API level :
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
if(Build.VERSION.SDK_INT >= 11)
{
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_CLEAR_TASK);
}
else
{
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
startActivity(intent);
Hope it helps ツ
You can set android:noHistory="true" in activities tag in AndroidManifest.xml which you don't want to save in stack.
Try to define one local broadcast receiver on top most parent activity or base activity :
private final class KillReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
}
Intialize and register broadcast receiver in onCreate() and unregister in onDestroy() on top most parent activity or base activity :
private KillReceiver clearActivityStack;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
clearActivityStack = new KillReceiver();
registerReceiver(clearActivityStack, IntentFilter.create("clearStackActivity", "text/plain"));
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(clearActivityStack);
}
Now call broadcast receiver when wan to clear all previous activity :
public void onClick(View v) {
Intent clearIntent = new Intent("clearStackActivity");
clearIntent.setType("text/plain");
sendBroadcast(clearIntent);
Intent intent = new Intent(getApplicationContext(),SomeActivity.class);
startActivity(intent);
}
I've read many answers on the same question but still I do not understand why my code doesn't work properly. I have a problem with (as I think) exchanging data between two activities.
I have 2 activities - the first contains ListView and an Add button.
When user presses Add new activity starts with the form to fill. When user completes the form he/she presses OK and my first activity starts again (it really does) and it should contain new item (but it doesn't).
This is my first activity:
public class DatabaseActivity extends Activity implements OnClickListener {
ArrayList<Student> students;
StudentDatabaseAdapter adapter;
ListView lvStudentList;
ImageButton imgBtnAdd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.database);
students = new ArrayList<Student>();
fillArrayList();
adapter = new StudentDatabaseAdapter(this, students);
lvStudentList = (ListView)findViewById(R.id.lvStudentsList);
lvStudentList.setAdapter(adapter);
imgBtnAdd = (ImageButton)findViewById(R.id.imagBtnAddStudent);
imgBtnAdd.setOnClickListener(this);
}
public void fillArrayList() {
//code here
}
#Override
public void onClick(View v) {
Intent intent;
intent = new Intent(this, WizardActivity.class);
startActivity(intent);
}
public void addStudent(Student student) {
students.add(student);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if(resultCode==RESULT_OK)
{
if(requestCode==2)
{
if (intent == null) {return;}
Student newStudent = new Student(intent.getStringExtra("name"), intent.getStringExtra("surname"),
intent.getStringExtra("last_name"), Integer.parseInt(intent.getStringExtra("year_of_birth")), R.drawable.default_ava);
addStudent(newStudent);
adapter.notifyDataSetChanged();
}
}
}
}
And that's my second activity:
public class WizardActivity extends Activity implements OnClickListener {
EditText etName, etSurname, etLastName, etYearOfBirth;
ImageButton imgBtnOK;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.wizard);
etName = (EditText)findViewById(R.id.etName);
//initializing other edit texts
imgBtnOK = (ImageButton)findViewById(R.id.imgBtnOK);
imgBtnOK.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(this, DatabaseActivity.class);
intent.putExtra("name", etName.getText().toString());
intent.putExtra("surname", etSurname.getText().toString());
intent.putExtra("last_name", etLastName.getText().toString());
intent.putExtra("year_of_birth", etYearOfBirth.getText().toString());
setResult(RESULT_OK, intent);
startActivityForResult(intent, 2);
}
}
There is nothing wrong with your notifyDataSetChanged(). You seem to be missing the way a secondary activity communicates results back to its caller activity.
DatabaseActivity.onClick() should call startActivityForResult() instead of startActivity().
WizardActivity.onClick() should just call finish() after setResult() (remove the startActivityForResult() call, it doesn't make sense there). Also notice that the intent you provide to setResult() can be an empty intent, i.e. Intent intent = new Intent();
After the secondary activity finishes, DatabaseActivity will be back to foreground and the result will be processed by DatabaseActivity.onActivityResult().
I think you haven't to start new activity in WizardActivity
try this :
WizardActivity
......
#Override
public void onClick(View v) {
Intent intent = new Intent(this, DatabaseActivity.class);
intent.putExtra("name", etName.getText().toString());
intent.putExtra("surname", etSurname.getText().toString());
intent.putExtra("last_name", etLastName.getText().toString());
intent.putExtra("year_of_birth", etYearOfBirth.getText().toString());
setResult(RESULT_OK, intent);
finish();
}
and in
DatabaseActivity
add if you want
#Override
protected void onResume (){
......
adapter.notifyDataSetChanged();
}
How do you change activities using DroidGap? Is there a way to get the current context even though we're using DroidGap?
public class MainActivity extends DroidGap {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isOnline() == true) {
super.loadUrl("http://myurl.com");
}
else {
Intent myIntent = new Intent(SOME CONTEXT...DroidGap.getContext(), LoadScreen.class);
startActivity(myIntent);
finish();
}
}
This solved my problem Intent myIntent = new Intent(getContext(), LoadScreen.class);