I have an app that uses intent-filters in the AndroidManifest.xml file to start an Activity when the Home button is pressed. Thing is, if my app is on that time in a different activity, the LoginActivity is started again and the user has to log in again. I want the Home button to do nothing if my app is on top.
How could I do that?
<activity
android:name="com.example.LoginActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Is not advisable to change the Home button functionality, because doing so it would be a negative user experience. Instead, you could store into a variable a boolean if the user is logged in, and if true, jump directly on to the main activity.
I don't know what is your launch activity, but if it is the login activity, you could check on the onStart method what I said, and then start the other activity.
You shoud to check by your own trigger (static variable?) that your app is working and user logged in early, then start another activity and finish current
OR
try this
android:launchMode="singleTop"
in your manifest to the activities.
There are three ways to do this:
Works between 2.3 and 4.0:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_HOME)) {
// do nothing
return true;
}
return super.onKeyDown(keyCode, event);
}
Also works between 2.3 and 4.0:
#Override public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
This involves overriding the method onUserLeaveHint():
#Override
protected void onUserLeaveHint() {
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
((AlarmManager) this.getSystemService(ALARM)).set(1,
System.currentTimeMillis(),
PendingIntent.getActivity(this, 0, intent, 0));
}
super.onUserLeaveHint();
}
Related
I'm making a parental control app where the app will ask for a password at a certain time. I want the activity where the app ask for a password can not be exitable before the parent give the right password. How can I do that?
Add the following permission to AndroidManifest.xml
<uses-permission android:name="android.permission.REORDER_TASKS" />
then in your activity
#Override
protected void onPause() {
super.onPause();
ActivityManager activityManager = (ActivityManager) getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.moveTaskToFront(getTaskId(), 0);
}
To disable Home Button
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
To disable Back Button
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Do nothing or catch the keys you want to block
}
I have a problem with Activity lifecycle and NFC:
I have a MainActivity with the AndroidManifest.xml entry:
<activity
android:name=".ui.main.MainActivity"
android:finishOnTaskLaunch="true"
android:launchMode="singleTask"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/androidbeam" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/nfctag" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="#xml/nfc_tech_filter" />
</activity>
where launchMode="singleTask" is used for NFC to prevent multiple MainActivity instances.
In MainActivity I have the following code:
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Timber.d("onCreate");
setContentView(R.layout.activity_main);
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
Timber.d("OnNewIntent");
handleIntent(intent);
}
private void handleIntent(Intent intent){
String action = intent.getAction();
String intent_type = intent.getType();
Timber.d("Intent action:" + action + "\n " + "Intent type:" + intent_type);
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
// Handle data from intent.getParcelableExtra()
Timber.d("onNFCDataReaded");
}
// and implementing creating of activity here
}
#Override
protected void onResume() {
super.onResume();
Timber.d("onResume");
enableNFCDispatch();
}
#Override
protected void onPause() {
Timber.d("onPause");
super.onPause();
disableNFCDispatch();
}
#Override
protected void onDestroy() {
super.onDestroy();
Timber.d("OnDestroy");
}
#Override
public void onBackPressed() {
super.onBackPressed();
Timber.d("OnBackPressed");
}
}
Everything works as expected, except for one use case:
When I am opening the application first with Android Beam or an NFC tag, onCreate() is called and it passes getIntent() to handleIntent() with the data received from another phone or an NFC tag. This works fine.
But after that, when I
click onBackPressed button inside MainActivity (i.e. exiting the application), and
then hold the Home button and in the overview screen select my application,
my application is opened again and onCreate() is called again. However, getIntent() returns the old intent with same data (intent.getAction(), intent.getParcelableExtra()) as I got with Android Beam or NFC tag!
I don't understand why! I expect to receive a new intent; the same as if the app is created when I click the application icon.
Can somebody help me with this?
Here is my MainActivity lifecycle:
MainActivity: onCreate
MainActivity: handleIntent
MainActivity: Intent action: android.nfc.action.NDEF_DISCOVERED
Intent type: application/androidbeam
MainActivity: onNFCDataReaded
MainActivity: OnResume
MainActivity: OnBackPressed
MainActivity: onPause
MainActivity: OnDestroy
//After that, I am holding Home Button and selecting my application from
//OverViewScreen, and getting next Log:
MainActivity: onCreate
MainActivity: handleIntent
MainActivity: Intent action:android.nfc.action.NDEF_DISCOVERED
Intent type:application/androidbeam
- // I do not expect it here !!!!!
MainActivity: onNFCDataReaded
MainActivity: OnResume
This is expected behavior. When you bring your activity to the background and later open the activity again from history (long-press home key), Android will recreate the previous activity stack and the activity will be launched with the same parameters as it was opened before. I.e. if it was launched with intent NDEF_DISCOVERED, it will, again, receive that intent.
However, you can easily detect if the activity was launched with the original intent or if it was launched from history. In the latter case, Android adds the flag FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY to the intent. Consequently, you can test for this flag in your handleIntent() method:
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) ||
NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
...
}
}
I need to override Home button for Lock Screen App. And I found the following answer which restart the app after 6 seconds on home button press.
protected void onUserLeaveHint() {
Intent i=new Intent(this,MainActivity123.class);
startActivity(i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));
Toast.makeText(this,"leaveHint",Toast.LENGTH_SHORT).show();
}
But I want to start the app immediately. So I guess thier was an answer saying if we make our app default Launcher app than thier will be no time gap.So i added in my manifest
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
But this is not working and app still restart after 6 sec.
what should i do.
So Spend some more researching and found another method {used to go to a default screen in launcher When you are already on home screen}
The method called automatically using appropriate flag in startActivity()
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Toast.makeText(this,"onNewEvent",Toast.LENGTH_SHORT).show();
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) !=
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) {
Toast.makeText(this,"onNewEvent",Toast.LENGTH_SHORT).show();
//++goHome++
startActivity(intent);
}
}
The method is get called But app still starts after 6 sec. SO no progress Any suggestion........
Try overriding the home button by implementing this method:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_HOME)) {
Toast.makeText(this, "You pressed the home button!", Toast.LENGTH_LONG).show();
return true;
}
return super.onKeyDown(keyCode, event);
}
:) Hope it helps.
i'm trying to develope an app for a tablet (ICS 4.0.3) that will be used in public places like bar, resturant ecc..
The user that uses that tablet ( so my application ) could not go in home and only administrator, setting a code, can go out.
What i've done is:
public class MainActivity extends Activity {
private Activity actual;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (getIntent().getBooleanExtra("EXIT", false)) {
finish(); // it doesn't work
}
}
#Override
public void onBackPressed() {
// do nothing!
}
}
MANIFEST:
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
</activity>
ADMINISTRATION DIALOG:
TEST1: // application is relaunched
Intent homeIntent= new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(homeIntent);
TEST2: // application is relaunched
System.exit(0);
TEST3: // it open settings (o.O)
Intent h = new Intent(Intent.ACTION_MAIN);
h.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
h.putExtra("EXIT", true);
context.startActivity(h);
My problem is that i can't go out from application.. how can i solve?
In TEST3 you've only provided ACTION_MAIN in the Intent. Android looks for apps that can handle this action and finds a long list of them. How should it know that it should launch yours?
I assume you've set your app as a HOME-screen replacement. Try adding this to the code for TEST3:
h.addCategory(Intent.CATEGORY_HOME);
I implemented a Splash Screen of my Android App....and I have a custom home button in my action bar that when click, it will be redirected to my dashboard Activity and not to my splash screen..Do you have any idea how to implement it?? I am newbie regarding android Application...
Please show me how to do it..I can't get any idea how to code it...
Any Responses are highly appreciated..Thanks
My menu item code
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menuitem1:
//code to be inserted here but I dont know how
break;
case R.id.menuitem2:
Log.i("This is Menu", "0");
super.onBackPressed();
break;
default:
break;
}
return true;
}
My Android Manifest
<activity android:name=".SplashScreen"
android:theme="#android:style/Theme.Holo.Light.NoActionBar.Fullscreen"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AndroidTabLayoutActivity"
android:logo="#drawable/logo"
android:label=""
>
<intent-filter>
<action android:name="com.droidnova.android.splashscreen.AndroidTabLayoutActivity" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
You can just use startActivity(<Intent for your dashboard activity>) instead of super.onBackPressed().
in OnClick of home button start dashboard activity as
home.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(currentclass.this,dashboardactivity.class);
startActivity(intent);
finish();
}
});
You say that the dashboard is a fragment in your AndroidTabLayoutActivity. Im supposing that you dont want to call that fragment from the current Activity you are in.
You could pass a parameter in the intent for opening AndroidTabLayoutActivity like this. (this code goes in the onOptionsItemSelected() method)
Intent intent = new Intent();
intent.setClass(this,AndroidTabLayoutActivity.class);
intent.putExtra("type","dashboard");
startActivity(intent);
Then in the AndroidTabLayoutActivity in the onCreate method you could check if this parameter exists.
if ( getIntent().getStringExtra("type","splash").equals("dashboard")) {
//start dashboard
} else {
//start splashscreen
}