Go back to launcher android programmatically - java

I use the following code to set my app as the default program. Press the home key to go to my app...
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
It also boots with DISABLE_KEYGUARD directly into my app, without needing to unlock the phone.
How can I change back to the default launcher programmatically? Meaning, how can I go back to android home screen?
I tried using System.exit(0) however it doesn't work - it just goes back to my app instead of the android home screen.
The following is my code.
It goes back to my APP automatically.
Please tell any problem in the code.
TesthomeActivity.java
public class TesthomeActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.button1);
btn.setOnTouchListener(exitappTouchListener);
}
OnTouchListener exitappTouchListener= new OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent arg1) {
// TODO Auto-generated method stub
if(arg1.getAction() == MotionEvent.ACTION_DOWN){
}
if(arg1.getAction() == MotionEvent.ACTION_UP ){
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
TesthomeActivity.this.startActivity(i);
finish();
System.exit(0);
}
return false;
}
};
}
StartupReceiver.java
public class StartupReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent)
{
Intent activityIntent = new Intent(context, TesthomeActivity.class);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(activityIntent);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.inno.testhome"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<application android:icon="#drawable/icon" android:label="#string/app_name" android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen">
<activity android:name=".TesthomeActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</activity>
<receiver android:name="StartupReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>

read this Is quitting an application frowned upon?
or use this
Intent i = new Intent();
i.setAction(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_HOME);
yourActivity.this.startActivity(i);
finish();
I think this will help you

If your app is set as the default launcher, the Android system will automatically restart your app whenever it quits. It no longer has any concept of the original home screen - as far as the operating system is concerned, your app is the home screen now.
This is why you are unable to get back to the default launcher by quitting your app.
The only way to achieve the result you want is to change the default launcher.

You need to query the PackageManager for the apps that respond to the Home intent.
You can then launch the correct one as you would start any other activity. Be sure to remove your app from the list before processing...
For useful info on that, I suggest #Commonsware's Launchalot sample app, which shows how to enumerate a list of apps that respond to a certain intent.
Check his code on github here.

Related

Adding a new project to existing project android application (How to move to next activity)

I've only watched and read tutorials from YouTube and on the internet but I need a specific instruction to this. (Still a student and just self-studying android development.)
I have a found a source code for that I want to make as reference in experimenting applications: https://github.com/vjycool97/Zomato-Search-API (credits to the owner)
I wanted to try it to appear after I tap the "Get Started" button on the welcome screen but the button intent doesn't work for me. The app just crashes.
public class WelcomeScreen extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome_screen);
Button gsbtn=(Button)findViewById(R.id.getstartedbtn);
gsbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i=new Intent(getApplicationContext(),MainActivity.class);
startActivity(i);
}
});
update
Logcat
java.lang.NullPointerException: Attempt to invoke interface method 'int android.database.Cursor.getCount()' on a null object reference
at e.alasse.foodiary.views.activities.MainActivity.onLoadFinished(MainActivity.java:382)
at e.alasse.foodiary.views.activities.MainActivity.onLoadFinished(MainActivity.java:66)
at android.support.v4.app.LoaderManagerImpl$LoaderObserver.onChanged(LoaderManagerImpl.java:250)
at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
at android.arch.lifecycle.LiveData.setValue(LiveData.java:282)
at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.setValue(LoaderManagerImpl.java:189)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManagerImpl.java:174)
at android.support.v4.content.Loader.deliverResult(Loader.java:132)
at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:109)
at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:41)
at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:258)
at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:83)
at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:490)
at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:507)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
EDIT 2:
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="e.alasse.foodiary">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="#mipmap/icon2"
android:roundIcon="#mipmap/icon2"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".WelcomeScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="e.alasse.foodiary.providers.RestaurantContentProvider"
android:authorities="e.alasse.providers.RestaurantContentProvider"
android:exported="false" />
<activity android:name=".views.activities.MainActivity"></activity>
<activity android:name=".ImagesActivity" />
<activity android:name=".UploadActivity" />
</application>
UPDATE
The get started button moved to the next activity but it crashes after, again.
I have this error
java.lang.RuntimeException: An error occurred while executing
doInBackground()
Updated version
https://drive.google.com/file/d/1udjQcT02b8sDTDA3udWDbx96X3rpCssJ/view?usp=sharing
First in your manifest you must declare your application class with name attribute.
add something like this to your manifest :
<application
android:name=".MyApplication"
the getCityId() method in MainActivity class throws nullpointer exception since you did not declare your application class so MyApplication.getContext() is null.
I add the line above and everything works fine.
In onLoadFinished method of MainActivity class, you could see this:
RestaurantInfoModel model = MyApplication.getGsonInstance().fromJson(cursor.getString(dataIndex), RestaurantInfoModel.class);
Which calls MyApplication's method getGsonInstance(), and to ensure this method executed successfully, you should add this line in your AndroidManifest.xml :
android:name=".MyApplication"
The detailed info about custom application is here

Android, no AppCompat, full screen - the most correct style?

Android app, strictly level 21 onwards only. Not using AppCompat.
Full-screen app with absolutely no bars.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.client.client">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Main"
android:screenOrientation="portrait"
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>
</application>
</manifest>
Am confused between:
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
versus...
android:theme="#android:style/Theme.DeviceDefault.NoActionBar.Fullscreen"
What is the best and most modern choice?
I don't understand the complete history of the difference between those and similar values in Android :/
Again, not using AppCompat, if that matters.
Here's a screenshot of how I want the app to look on all devices:
what is the best and most modern choice?
With a minSdkVersion of 21+, you can use themes based off of Theme.Material, such as Theme.Material.Light.NoActionBar.Fullscreen.
An answer for 2022:
I have found that the only way I can do it these days is:
// completely fullscreen:
protected void utterlyFullScreen() {
// go top the physical top (ie under the statusBars):
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
WindowInsetsControllerCompat windowInsetsController =
ViewCompat.getWindowInsetsController(getWindow().getDecorView());
if (windowInsetsController == null) { return; }
// hide the bars:
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars());
// statusBars top one. navigationBars bottom one. systemBars both.
// handle reveal:
windowInsetsController.setSystemBarsBehavior(
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
// also:
// windowInsetsController.setAppearanceLightNavigationBars(true);
// or, do that in theme
}
I call that in every activity onCreate, after super, but before setting the view.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
utterlyFullScreen();
setContentView(R.layout.activity_main);
I am minSdk 24 as of writing.

Pushes not received after the app is closed

Before labeling this as a duplicate:
I've read at least 15 similar threads and each and every one is either using the old Parse code (the now deprecated setDefaultPushCallback) or the problem was a result of calling Parse.initialize(...) in an activity and not in the Application class. But this is not applicable to my case. The official example (which I'm using) is evidently doing it right, so the code is already in the Application class.
I've downloaded the Push Starter example from Parse's official guides and tried it out on an emulator. I receive pushes only while the app is running. The moment's it's closed (removed from the "recent apps" list, not force killed), I no longer get pushes. Which makes the entire feature rather useless... I tried with and without GCM, the behavior is the same.
Any clues what could possible be wrong? All classes are the stock example ones, nothing overridden or added by me (except for the id/key and the ParsePush.subscribeInBackground call which I copied from the guide). Weirdly enough, the example code did not contain ParsePush.subscribeInBackground and the QuickStart does not mention it. It even gives a Test button that supposedly sends a push which I never receive, with or without subscribeInBackground. The only way I've been able to get a push so far was with subscribeInBackground and sending a push manually though the web console, and only so if the app is running. The web console also keeps telling there's 2 registered devices... which is untrue.
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.parse.starter"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!--
IMPORTANT: Change "com.parse.starter.permission.C2D_MESSAGE" in the lines below
to match your app's package name + ".permission.C2D_MESSAGE".
-->
<permission android:protectionLevel="signature"
android:name="com.parse.starter.permission.C2D_MESSAGE" />
<uses-permission android:name="com.parse.starter.permission.C2D_MESSAGE" />
<application
android:name=".ParseApplication"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:allowBackup="true">
<activity
android:name=".ParseStarterProjectActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.ParsePushBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<!--
IMPORTANT: Change "com.parse.starter" to match your app's package name.
-->
<category android:name="com.parse.starter" />
</intent-filter>
</receiver>
</application>
</manifest>
ParseApplication:
package com.parse.starter;
...
public class ParseApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Initialize Crash Reporting.
ParseCrashReporting.enable(this);
// Enable Local Datastore.
Parse.enableLocalDatastore(this);
ParseUser.enableAutomaticUser();
// Add your initialization code here
Parse.initialize(this, "***", "***");
ParseACL defaultACL = new ParseACL();
// Optionally enable public read access.
// defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
ParsePush.subscribeInBackground("", new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
} else {
Log.e("com.parse.push", "failed to subscribe for push", e);
}
}
});
}
}
Just to clarify why you are seeing this behaviour, Parse has two different ways for delivering push notifications:
"Parse way": the Parse SDK has a component running in your app, which keeps a connection to the Parse backend servers. This will only work when your app is actually running, because killing it breaks the connection with the Parse backend.
GCM "Google" push notifications: This works via Google Play Services, an app which is always running in the background and that can start your app when needed. This will always work, unless you force stop the application.
In your case you are there is a package name conflict: com.parse.starter is the package name that was actually included in the example. This causes GCM not to work, because it already knows the package under a different signature. Changing your package name to something unique like com.parse.kaqqao should solve the trick.
There are a few reasons for this:
There are two BroadcastReceiver viz the "com.parse.ParsePushBroadcastReceiver" and "com.parse.GcmBroadcastReceiver". I believe that the first receiver is getting prioritized over the GCMBroadcastReceiver and thus the behavior is not affected by removing or keeping this receiver. It could also be due to action "com.parse.push.intent.RECEIVE", which might be handling the push messages RECEIVE action. If both the receiver perform the same task of parsing the Push message (starting the same service in background), then include the intent-filter inside one receiver and let it handle all kinds of push messages. Since GCMBroadcastReceiver holds the C2DM permission.
Try changing the order of the two broadcast receiver tags in the manifest. (Keep GCMBroadcastReceiver before the ParsePushBroadcastReceiver)
It could be due to android:exported="false", maybe it prevents the Receiver from listening to the push messages sent by server. Try changing to true.

No activity found to handle custom intent

Using a customer defined activity and i've declared the intent action in the manifest.xml
Here's the manifest file with the error
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.labs.dangerousapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="18" />
<!--
TODO - Using a permission element,
define a custom permission with name
"course.labs.permissions.DANGEROUS_ACTIVITY_PERM"
and "dangerous" protection level.
-->
<permission
android:name="course.labs.permissions.DANGEROUS_ACTIVITY_PERM"
android:protectionLevel="dangerous"
>
</permission>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- TODO - enforce the custom permission on this Activity -->
<activity
android:permission="course.labs.permissions.DANGEROUS_ACTIVITY_PERM"
android:name=".DangerousActivity"
android:label="#string/app_name" >
<!--
TODO - add additional intent filter info so that this Activity
will respond to an Implicit Intent with the action
"course.labs.permissions.DANGEROUS_ACTIVITY"
-->
<intent-filter >
<category android:name="android.intent.category.DEFAULT" />
<action android:name="course.labs.permissions.DANGEROUS_ACTIVITY" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Here's where the intent was invoked in the program
Code:
package course.labs.permissionslab;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class GoToDangerousActivity extends Activity {
private static final String TAG = "Lab-Permissions";
private static final String DANGEROUS_ACTIVITY_ACTION = "course.labs.permissions.DANGEROUS_ACTIVITY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.go_to_dangerous_activity);
Button startDangerousActivityButton = (Button) findViewById(R.id.start_dangerous_activity_button);
startDangerousActivityButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
startDangerousActivity();
}
});
}
private void startDangerousActivity() {
Log.i(TAG, "Entered startDangerousActivity()");
startActivity(new Intent(DANGEROUS_ACTIVITY_ACTION));
}
}
Please let me know if any other info will hell, I've been tried everything i know and not sure why i'm getting this error again.
Did you installed the first App that has the manifest before calling using the second App?
[EDIT]
To check if a activity is registered to some Intent, you can use adb.exe available on Platform-tools folder to list all intents configured on the device.
To do that, on prompt execute the command below:
adb shell dumpsys package > packages.txt
Then open packages.txt and find for action name course.labs.permissions.DANGEROUS_ACTIVITY. Should have a activity associate with that action.
Try so:
startActivity(new Intent(getApplicationContext(), DANGEROUS_ACTIVITY_ACTION.class));
This is the normail way of doing it
[EDIT]
OR (note the different declaration of DANGEROUS_ACTIVITY_ACTION)
private static final String DANGEROUS_ACTIVITY_ACTION = ".DangerousActivity";
// ...
startActivity(new Intent(DANGEROUS_ACTIVITY_ACTION));
I use this in a SplashScreen Activity to call the Main Activity (after done loading my graphics from SVG files).
You need to run "DangerousApp" before running "GoToDangerousActivity".
This is because your dangerous app is not even installed on the device. If you were trying to do this from android studio, by default studio would try to launch the app which won't be successful because of the permission it needs. To install your dangerours, modify studio's launch settings to not to run the app right away. I got the same issue.

Android - Broadcast Receiver not being fired

I know this has been asked ALOT on here, but I have been scouring the interwebs for hours and I have even reused some of my previous code for receiving sms' and I got...nothing.
So, here goes, basic app to receive SMS but the app never receives the intent. I thought the intent may be ignored if the text is sent from the same phone but that does not seem to be the case, as other apps pick up the text fine.
Here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.encima.smsreceiver"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MessageReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
</manifest>
And, here is the receiver, nothing seems to be new here, so I have no idea what the problem is:
package com.encima.smsreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class MessageReceiver extends BroadcastReceiver {
private static final String TAG = "Message recieved";
#Override
public void onReceive(Context context, Intent intent) {
Bundle pudsBundle = intent.getExtras();
Object[] pdus = (Object[]) pudsBundle.get("pdus");
SmsMessage messages =SmsMessage.createFromPdu((byte[]) pdus[0]);
Log.i(TAG, messages.getMessageBody());
Toast.makeText(context, "SMS Received : "+messages.getMessageBody(),
Toast.LENGTH_LONG).show();
}
}
The debug phone I am using is running 2.2.2 and I have other apps running that detect sms, including some of my own.
Any insight into this would be appreciated!
Thanks
Because the SMS broadcast intent is sent by
Context.sendOrderedBroadcast(...),
if any other app registers the BroadcastReceiver and calls abortBroadcast, the other receiver will not get the broadcast.
To increase the probability of your app receiving the broadcast create an IntentFilter, use IntentFilter.setPriority.
I do not know if this is your problem but you should definitelly try this:
Instead of ".MessageReceiver" put android:name = "com.encima.smsreceiver.MessageReceiver"
This is fix that workout many times for me when something doesn't get called.

Categories