I'm trying to get VoiceInteractor, but the getVoiceInteractor() method always returns null. In the manifest, I wrote the following:
<activity android:name=".Activity_2">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.VOICE" />
</intent-filter>
</activity>
Activity_1:
protected void onCreate(Bundle savedInstanceState) {
startActivity(new Intent(Activity_1.this, Activity_2.class));
}
Activity_2:
protected void onCreate(Bundle savedInstanceState) {
VoiceInteractor mInteractor;
mInteractor = getVoiceInteractor();
}
The documentation seems a bit unclear, but I found the following clues:
startLocalVoiceInteraction() seems to be needed to be able to get the VoiceInteractor
onLocalVoiceInteractionStarted() seems to indicate when you can call getVoiceInteractor
The last clue came from onGetDirectAction where it states:
To get the voice interactor you need to call getVoiceInteractor() which would return non null only if there is an ongoing voice interaction session
This means your code should look something like this:
public class YourActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
startLocalVoiceInteraction(new Bundle());
}
#Override
public void onLocalVoiceInteractionStarted() {
getVoiceInteractor(); // Should be non-null here
}
}
I want to only show my menu in my main activity then have a back button from my other activities instead of a menu. Right now I am just wondering how would I would remove the menu from the action bar on the activities I don't want it on.
My Manifest:
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".Insulter"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="Favourites"
android:launchMode = "singleInstance">
</activity>
<activity
android:name="Settings"
android:launchMode = "singleInstance">
</activity>
</application>
My menu opener inside my main activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
Intent startSettings = (new Intent(Insulter.this,Settings.class));
startActivity(startSettings);
return true;
} else if (id == R.id.exit_the_app) {
finish();
return true;
} else if (id == R.id.favourites) {
Intent startFavs = (new Intent(Insulter.this, Favourites.class));
String[] objects = new String[favs.size()];
favs.toArray(objects);
final ArrayList<String> list = new ArrayList<>(Arrays.asList(objects));
startFavs.putStringArrayListExtra("favs",list);
startActivity(startFavs);
return true;
}
return super.onOptionsItemSelected(item);
}
If you want menu in any of your activity, then you need to override onCreateOptionsMenu and onOptionsItemSelected...
If you don't want menu, simply don't override these methods in your activity...
Activity.onCreateOptionsMenu is the place where it gets created. Just don't override this method or let it return false to not show the menu.
You must return true for the menu to be displayed; if you return false it will not be shown.
If you're using the same implementation for all your activities, define a field boolean isMain and return it from onCreateOptionsMenu
public boolean onCreateOptionsMenu (Menu menu) {
if (!isMain)
return false;
[creating the menu here like before]
}
For each activity that you create, there must be a menu file associated with it in the res/menu folder. Simply delete or comment the corresponding <item> tags. You may experiment with them by looking at the output show in the preview screen.
Note: I think this works only when an activity is created automatically using the UI (i.e not manually) since the corresponding menu file is generated automatically with it.
You need to use following steps to remove options menu and add back button in your non-main activities --
Don't override onCreateOptionsMenu method.
call getActionBar().setDisplayHomeAsUpEnabled(true) in your activity's onCreate method.
Override onOptionsItemSelected method in following way--
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
finish();
return super.onOptionsItemSelected(item);
}
}
I have an activity that is using the Theme.Dialog style. It's a popup for my quiz game, for the wrong answer. But I have a problem. User can click outside the popup dialog themed activity and click on the next question. How to prevent that? I blocked back button and that works fine.
Also, when a user clicks on the popup or outside of it, it starts counting the ON time again. My popup stays ON for 2500 ms. How to prevent that also?
So, basically I don't want to allow any click outside my popup and don't want to reset my delay time when someone clicks on the screen.
Here's the code of the popup window:
public class WrongAnswer extends Activity{
MediaPlayer sound;
TextView wrong;
String correctAnswer, correct;
public final int delayTime = 2500;
private Handler myHandler = new Handler();
public void onUserInteraction(){
myHandler.removeCallbacks(closePopup);
myHandler.postDelayed(closePopup, delayTime);
}
private Runnable zatvoriPopup = new Runnable(){
public void run(){
finish();
}
};
#Override
public void onBackPressed() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.wrong);
Bundle extras = getIntent().getExtras();
if(extras !=null) {
tacno = extras.getString("correctAnswer");
}
inicijalizujVarijable();
myHandler.postDelayed(closePopup, delayTime);
}
private void inicijalizujVarijable() {
wrong = (TextView) findViewById(R.id.tvWrong);
wrong.setText("Wrong answer!\nCorrect answer is:\n\n" + correct);
}
}
My activity in manifest:
<activity
android:name="com.myquiz.myquizgame.WrongAnswer"
android:label="#string/app_name"
android:theme="#android:style/Theme.Dialog"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="com.myquiz.myquizgame.WRONGANSWER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
If I got you correctly, this question had been already asked. Here is the answer, and according to it you need to call a setter method on activity, that will close your activity dialog:
this.setFinishOnTouchOutside(false);
I hope it will help you.
Second, every time when user touches WrongAnswer activity — you start new delayed task and cancel previous one here:
public void onUserInteraction() {
myHandler.removeCallbacks(zatvoriPopup);
myHandler.postDelayed(zatvoriPopup, delayTime);
}
that's why you have problems with timer
I have ActivityA and ActivityB. ActivityB is called from ActivityA.
I wanted to retain the object of ActivityA, when I press back button of ActionBar or back button of device.
I have created a Singleton object to save my object and to get my object.
onPause() I am saving the object and onResume() method I am getting the object.
My problem here is the behaviour is different, the object that I get when back button of Action (in ActivityB) is different from the object that I get when back button of back button is clicked.
Here is the code:
protected void onPause() {
//resetSort();
super.onPause();
MySingleton.getInstance().setMyObject(myObject);
}
#Override
protected void onResume() {
super.onResume();
myObject = MySingleton.getInstance().getMyObject();
}
Here is my manifest file.
<activity
android:name=".ActivityA"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
>
</activity>
<activity
android:name=".ActivityB"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name" >
</activity>
Code from ActivityB:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
Any solution is appreciated. Thanks
The most reliable way is to use SharedPreferences. It's both thread safe and remains even if your app is killed off.
Google's Storage Options guide is also definitely worth a look if you haven't had a chance to review it yet.
To save a String you would use:
String str = "abc";
getSharedPreferences("filename", Context.MODE_PRIVATE).edit().putString("String Name", str).commit();
And then to retrieve it:
String str = getSharedPreferences("filename", Context.MODE_PRIVATE).getString("String Name", "default string")
I have an app start by Splash activity screen for 5 seconds Then open Login activity screen then after you put correct user and password open the Menu activity (listActivity) then each row click open MyCity activity.
UPDATE:
What I'm trying to get is: where ever you are in my app, and you go away from my app for any reason not only when you press the home button but also FOR EXAMPLES:
You press home button to check another app then want to return to my app .
You have notification show new message on whatsup or email, you open your whatsup or open email, then return to my app .
3- You left your mobile for period of time then you want to check my app again .
4- you press power button to close the phone ( lock the screen) , then open the lock and want to return back to my app .
what I mean any time you go away my app for any reason but whithout press back back back button which will exit the whole app
then want to return again to my app must open to
you the login screen to re enter your usename and password again.
I Called finish(); for both Splash activity and Login activity .
I tried:android:clearTaskOnLaunch="true" in the Login activity in the manifest but it doesn'thing.
Any advice will be appreciated,
PLEASE WRITE FULL WORKING CODE.
LOGIN ACTIVITY:
public class Login extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
Button b = (Button) findViewById(R.id.loginbutton);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
EditText username = (EditText) findViewById(R.id.login);
EditText password = (EditText) findViewById(R.id.password);
if(username.getText().toString().length() > 0 && password.getText().
toString().length() > 0 ) {
if(username.getText().toString().equals("test") && password.getText().
toString().equals("test")) {
Intent intent = new Intent(Login.this, Menu.class);
startActivity(intent);
finish(); }
} }
}); } }
Menu Activity :
public class Menu extends ListActivity {
String classes[] = { "City1", "City2", "City3", "City4", "City5"};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(Menu.this,
android.R.layout.simple_list_item_1, classes));
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
String cheese = classes[position];
try {
Class ourClass = Class.forName("com.test.demo.MyCity");
Intent ourIntent = new Intent(Menu.this, ourClass);
ourIntent.putExtra("cheese", cheese);
startActivity(ourIntent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}}
MyCity Activity :
public class MyCity extends Activity {
TextView tv1;
String city;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.city);
initializeTextViews();}
private void initializeTextViews() {
tv1=(TextView)findViewById(R.id.city_tv);
city=getIntent().getStringExtra("cheese");
if(city.equalsIgnoreCase("City1")){
tv1.setText(Html.fromHtml(getString(R.string.city1)));}
else if(city.equalsIgnoreCase("City2")){
tv1.setText(Html.fromHtml(getString(R.string.city2)));}
else if(city.equalsIgnoreCase("City3")){
tv1.setText(Html.fromHtml(getString(R.string.city3)));}
else if(city.equalsIgnoreCase("City4")){
tv1.setText(Html.fromHtml(getString(R.string.city4)));}
else if(city.equalsIgnoreCase("City5")){
tv1.setText(Html.fromHtml(getString(R.string.city5)));}
}}
MY MANIFEST:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.demo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".Splash"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Login"
android:label="#string/app_name"
android:clearTaskOnLaunch="true">
<intent-filter>
<action android:name="com.test.demo.LOGIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".Menu"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.test.demo.MENU" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".MyCity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.test.demo.MYCITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
SECOND UPDATE : i reached halfway to what i want but still some steps i can't achieve it explained as below :
BY applying android:clearTaskOnLaunch="true" to Splash activity ,
and prevent back button behaviour on Menu activity :
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(true);
return true;
}
return super.onKeyDown(keyCode, event);
} }
SO now when press home button away my app then return to my app its:
go directly to Login activity.
but main goal now is :
if :
SCREEN LOCKED when you are away from your mobile , or press lightly the power button to lock the phone .
or
OPENED MESSAGE from notification
or
OPENED EMAIL from notification
or
you have CALL and answer it ,
THEN return to my app it does not go to login activity but you will return to the page where you was befor .
ANY ADVICE PLEASE , THANKS.
THIED UPDATE :
i used another code for override home button and control the back button rather than appling :android:clearTaskOnLaunch="true" to Splash activity in manifest , just apply the down code to Menu activity:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(true);
return true;}
else if (keyCode == KeyEvent.KEYCODE_HOME) {
Intent i=new Intent(Menu.this,Login.class);
startActivity(i);
finish();
return true;}
return super.onKeyDown(keyCode, event);}
If I understand you right, your goal is that users have to enter username and password again, when they come back to your App. So I think the most logical way to achieve this would be to add a check in all your Activities onResume() method to see if you have a username and password and if not, simply go to the login activity. Easiest way would be to have a BaseActivity implementing the check and let all your other activities (except for spash and login) inherit from that BaseActivity.
in pseudo java code
class BaseActivity extends Activity {
onResume() {
super.onResume();
if (!havingUsernameAndPassword()) {
startActivity(loginActivity);
finish();
}
}
}
class AnyOfYourActivitiesExceptSpashAndLogin extends BaseActivity {
onResume() {
super.onResume();
// ... further code
}
// ... further code
}
The implementation of havingUsernameAndPassword() of course depends on how you store the username and password in your login activity. A very simple way would be to store them in some static class members, so they'd survive as long as the Application runs.
Update: a more concrete example
I made a new example also showing how you can save the login data on login to be able to check it later on. Actually it would make even more sense to have just a flag 'loggedIn' and some user-id, but that depends upon your implementation, so I'll stick with username/password here.
class SimpleDataHolder {
public static String username = null;
public static String password = null;
}
class LoginActivity extends Activity {
// ...
// when user has entered valid username/password, store them in SimpleDataHolder:
SimpleDataHolder.username = username; // <-- store username entered
SimpleDataHolder.password = password; // <-- store password entered
}
class BaseActivity extends Activity {
onResume() {
super.onResume();
if (SimpleDataHolder.username == null || SimpleDataHolder.password == null) {
startActivity(loginActivity); // <-- go to login
finish(); // <-- end current activity
}
}
}
class AnyOfYourActivitiesExceptSpashAndLogin extends BaseActivity {
// ... your existing code (if any)
onResume() {
super.onResume(); // <-- this calls BaseActivity.onResume() which checks username/password
// ... your existing code (if any)
}
An application CANNOT re-route the home button without modifying the framework code. Sorry this is NOT possible...
To your second update problem I would suggest overriding the OnResume() method, but you must be careful with what you do in it. I would also suggest you study on how the android lifecycle works.
This is my suggestion :
Have a key in SharedPreferences called exit. In the onCreate() set the value of exit to false
public void onCreate(Bundle ..)
{
SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor=preferences.edit();
editor.putString("exit","false");
editor.commit();
.....
}
then in onResume() check the value of exit. If it is true, take the user to the login screen else do not do anything .
public void onResume()
{
super.onResume();
SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
String exit=preferences.getString("exit","");
if(exit.equals("true"))
{
Intent i=new Intent(this_activity.thi,login_activity.class);
startActivity(i);
finish()
}
}
then in onPause() set the value of exit to true.
public void onPause()
{
super.onPause();
SharedPreferences preferences=PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor=preferences.edit();
editor.putString("exit","true");
editor.commit();
}
You said that you have taken care of the backbutton. Then this should do it. Your app will always return to the login screen.
Here is the solution I came up with.
Please Download the project at the end of the blog post and test it.
Tested on:
Samsung S3 running android 4.0.4
Emulator running android 2.3.1
The basic idea: We will create a RequireLoginActivity which will be extended by all our activities except the LoginActivity.
Three cases should be captured when the onResume function is called:
Jumping from one RequireLoginActivity to another RequireLoginActivity using a flavor of startActivity.
Jumping from one RequireLoginActivity back to a previous RequireLoginActivity by finishing the current activity.
Coming back to a RequireLoginActivity after hiding it (we should here show the login!)
The basic idea of my solution is to have 2 counters: number of Started activities (startCounter) and number of Paused activities (pauseCounter). Each time an activity starts we will increment startCounter. Similarly, when an activity pauses, pauseCounter should be incremented. In our onResume function, we will decide whether to go to the Sign in by comparing the 2 counters. We will gotoLogin() if the 2 counters are equal!
Let me explain:
At any time, case 1 can be captured simply because upon starting new activities, our startCounter will always be greater that pauseCounter by 1. This is true because we will always have one extra activity started but not paused.
Also, case 3 is easily captured, because once you leave our app, say, using the HOME button, we will increment the pauseCounter and the 2 counters will become equal. Once the app is resumed, the onResume will decide to gotoLogin().
Case 2 is a bit tricky, but simple as well. The trick is by overriding the finish() function and decrementing the startCounter once and the pauseCounter twice in it. Remember that when finishing the activity, onPause is called and our counters are equal. Now by decrementing startCounter once and pauseCounter twice, we ultimately returned to the counters' values of the previous activity, and startCounter will remain greater the pauseCounter by 1 when the previous activity resumes.
Another workaround will be to create a activity(FinisherActivity) and call finish() in its onCreate() method. Then whenever you need to finish a activity on pressing the home button or back button and prevent it from staying on the stack just use an Intent to call FinisherActivity . But remember to setFlags for the intent to Intent.FLAG_ACTIVITY_CLEAR_TOP...I know its not an efficient approach, but it should work..
Actually I dont think i'm sure what exactly your asking, Do you want to press the Home Key built into your android device and start an activity?
Homekey listener
Try This:
if it works then awesome, just through an intent in there to call your login activity
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.KEYCODE_HOME) {
Toast.makeText(MainActivity.this, "Home Key is pressed
Toast.LENGTH_LONG).show();
return true;
}
Toast.makeText(MainActivity.this, "Didnt work", Toast.LENGTH_SHORT)
.show();
return super.dispatchKeyEvent(e);
};
what you are asking is against the way that android works .
when the user presses the home button , he expects that when he returns to the app , everything will stay as it was before , unless he wasn't there for a long time or if he ran a resource consuming app .
it's as if on windows , when you click ALT+TAB , you won't expect to see login on the email client (or messenger , or whatever app you use) .
in any case , you can use onWindowFocusChanged together with any of the functions of activity (onResume,onStart,onRestart,onPause,onStop,...) , and handle only the relavant cases you wish to use .
it's not possible because the home button is exclusive to call launcher application, but you can do your app a launcher application, running in kiosk mode for example, see it and it.
to turn a activity on launcher activity add this on itentfilter on manifest.xml
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
You can't override the home button default behaviour. You achieve the desired result by clicking back button, Home button's default behaviour is to goto Home Screen. My suggestion Override Back Button. Then using intent and setting flags properly you can goto login screen.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
super.onKeyDown(keyCode, event);
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
Intent i= new Intent("yourpackage.login");
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(i);
finish();
break;
}
return super.onKeyDown(keyCode, event);
}
It is difficult to tell exactly what you are asking, however I believe this is what you are looking for: How to make splash screen not to load if app is already in memory . To summarize my post there:
This is a design problem. Your launcher activity should not be your splash screen activity. Instead, open your splash activity in your main activity's onCreate method. That way, if it is opened fresh, onCreate is called and the splash screen is shown. Otherwise, if the app is merely resumed, which calls onResume, there would be no call to open the splash screen activity.
Then you can change your manifest to this:
<activity
android:name=".ui.MainActivity"
android:noHistory="true"
android:screenOrientation="portrait"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".ui.SplashActivity"/>
Have you tried the android:noHistory activity attribute (for each of your activities) in the Android Manifest? That sounds like exactly what you are looking for.
Your code is almost correct: to clear the activity stack when launching your application, you should add android:clearTaskOnLaunch="true" to your root activity, which is Splash, not Login (it will be the first one running, see this question on determining the root activity)!
From the documentation:
This attribute is meaningful only for activities that start a new task
(the root activity); it's ignored for all other activities in the
task.
So if you move the attribute in the manifest from Login to Splash, it should work, your application will always start with the splashscreen.
UPDATE: To restart your app even on incoming calls, screen lock or notifications, you have to add android:noHistory="true" (docs here) to all your other activities, or call finish() in all their onPause() methods.
It's worth mentioning that our answers are so different and complicated because what you want to achieve is totally against core Android concepts (for example, here is a good article on exiting apps), so really, don't do anything like this outside your private app.
You should call finish() in all your activities' onPause() methods except Login activity. And you can call startActivity(new Intent (this, LoginPage.this)) in their onResume() method. So whenever the activities will come to foreground, user will be redirected to Login page again.
My little efforts may helps you, I had successfully Override the HOME button(below Android 4.0)
You can mould the code according to your requirement.
Answer on SO
Source at GITHUB
As you can now handle Home button so you can easily create your own logic to perform you Application flow.
this is you targetted event
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if ( (event.getKeyCode() == KeyEvent.KEYCODE_HOME) && isLock) {
//Logic when Home button pressed
return true;
}
else
return super.dispatchKeyEvent(event);
}
Hoping this will definitely going to meet our requirements.
Note: All this is for capturing Home Button for others you can manage