Launch an application from another application on Android, maintaining state - java

With the code below, I can open applications such as: Google Maps, calculator and
retain their state when they pass to foreground:
Intent i;
PackageManager manager = getPackageManager();
try {
i = manager.getLaunchIntentForPackage("com.google.android.apps.maps");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (i == null)
throw new PackageManager.NameNotFoundException();
i.setAction("android.intent.action.VIEW");
startActivity(i);
} catch (PackageManager.NameNotFoundException e) {
}
My problem is with an application created by me, because my application does not maintain the state. She is always restarted.
I have tried to use the properties in the manifest: launchMode, alwaysRetainTaskState, always unsuccessful.
Thanks in Advance

The android activity has different stages like Pause and resume which is called when an activity is paused. If the foreground activities stopped , the app may even visible in an paused state. In such cases you need to override your onPause() methods to say to your activity what to do if it paused.
Add the logic you need to perform when your activity paused in the onPause() method.
#Override
public void onPause() {
super.onPause(); // Always call the superclass method first
do some task here...
if (connectServer) {
pauseDownloadData();
}
}
when you resume your activity, it will invoke onResume()
public void onResume() {
super.onResume(); // Always call the superclass method first
do some task here...
if (connectServer) {
resumeDownloadData(); // Local method to handle camera init
}
}

Problem solved, with the solution below. Now I can start my application, if it is closed or resume (resume in any activity).
The code that starts the application is (Launcher):
Intent i;
PackageManager manager = getPackageManager();
try
{
i.addFlags(0);
i.setPackage(null);
if (i == null)
throw new PackageManager.NameNotFoundException();
startActivity(i);
}
catch (PackageManager.NameNotFoundException e)
{
}
My application that starts, has the following manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".Main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Screen2"
android:label="#string/screen2Title"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTask" >
</activity>
<activity android:name=".Screen3"
android:label="#string/screen3Title"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTask" >
</activity>
</application>
</manifest>
Now the application is resumed to any activity, without ever navigate to the root activity.

Related

Restart service on device reboot

I have a program with a service and if I reboot my device also the service should Restart. But this only works on the Emulator if I try this on my real device the service doesn't start at all.
Does someone know what I'm doing wrong or why it only works on Emulator?
BroadcastReviever:
#Override
public void onReceive(Context context, Intent intent) {
//we double check here for only boot complete event
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED))
{
//here we start the service
Intent serviceIntent = new Intent(context, UploadService.class);
context.startService(serviceIntent);
}
}
Manifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="Upload FTP"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver
android:name=".BootCompletedIntentReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter >
</activity>
<service
android:name=".UploadService"
android:isolatedProcess="false"
android:exported="true"
android:enabled="true"/>
</application>
The emulator is at API 23 and real device is API 27.
I'm Building for a min API Level 23 and max API Level 27
EDIT
Now I have also tried the program with a emulator and android API 27 and there when I start my program and then I restart the emulator, the emulator doesn't start any more. As soon as the emulaor has started he begins to reboot again and that in a endless loop. (Real device starts normal just doesn't restarts service)
try to use LOCKED_BOOT_COMPLETED receiver as follow:
<receiver
android:name=".BootReceiver"
android:directBootAware="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/>
<!-- For pre-N devices -->
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
don't forget permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
take a look here for more explanation
Now I fixed in on my own it was easier then i thought
public class BootCompletedIntentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i=new Intent(context, YourClass.class);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
context.startForegroundService(i);
}
else {
context.startService(i);
}
}
I had some weird experience if I don't put full URI,
for example .BootCompletedIntentReceiver would become com.company.BootCompletedIntentRecevier.
I know it sounds dumb but I had many weird regressions when not explicitly stating things on the Manifest with modern SDKs.

OneSignal Android not launching app with custom onNotificationOpened handler

I am attempting to migrate an app from Parse to OneSignal. Things have been running fairly smooth except for one issue. If the app has not already been started, clicking (opening) the notification does not launch the app and bring it to the foreground.
I am using a custom onNotificationOpenedHandler:
Main Activity, onCreate
// Init OneSignal
OneSignal.startInit(this).setNotificationOpenedHandler(new NotificationOpenHandler()).init();
NotificationOpenedHandler, also in the launcher Main Activity:
class NotificationOpenHandler implements OneSignal.NotificationOpenedHandler {
// This fires when a notification is opened by tapping on it.
#Override
public void notificationOpened(OSNotificationOpenResult result) {
JSONObject data = result.notification.payload.additionalData;
String stationName = data.optString("stationName");
String timestamp = data.optString("timestamp");
String filename = data.optString("filename");
String url = getString(R.string.callResourceUrl) + filename;
Log.d("APP", "Notification clicked");
Intent intent = new Intent(getApplicationContext(), CallActivity.class);
intent.putExtra("stationName", stationName);
intent.putExtra("time", timestamp);
intent.putExtra("url", url);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
Here is my Android Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.opheliadesign.tevfd">
<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.RECEIVE_BOOT_COMPLETED" />
<application
android:supportsRtl="true"
android:allowBackup="true"
android:icon="#drawable/icon"
android:label="#string/app_name"
android:logo="#drawable/ic_launcher"
android:launchMode="singleInstance"
android:theme="#style/Theme.Tevfd">
<activity android:name="com.example.app.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".CallActivity"
android:label="#string/title_activity_call"
android:parentActivityName=".MainActivity"
android:screenOrientation="portrait" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.app.MainActivity" />
</activity>
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT" android:value="DISABLE" />
</application>
</manifest>
Any ideas?
UPDATE
Previously, using Parse, I utilized a BroadcastReceiver with a PendingIntent. It seems a bit unclear how to accomplish this with OneSignal as so much seems to be configured automatically.
If I remove the custom Intent, the application comes to the foreground.
Any help would be greatly appreciated.

Configuring the google account programmatically in Android

i need some help, i was trying configuring the google account behind the android, the main idea is don't use the wizard to configure the google account, i need do this by code, i was searching, but don't successfully, the only way I was trying to do was the following, but I believe that this is merely a way to make my current application tivese access the account I'm trying to use, but still without success
#Override
public void onClick(View v) {
try{
AccountManager mgr = AccountManager.get(this);
Account acc = new Account("sexo#gmail.com", "com.google");
if(mgr.addAccountExplicitly(acc, "pass", new Bundle())) {
Toast.makeText(MainActivity.this, "Done", Toast.LENGTH_LONG);
}
}catch(Exception e){
Log.d("test", e.getMessage());
Log.d("test", e.toString());
e.getStackTrace();
e.printStackTrace();
}
And this is my manifest used
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.actteste"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permaission.INTERACT_ACROSS_USERS_FULL"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:installLocation="internalOnly">
<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>
<service android:name="com.company.demo.account.AuthenticatorService" android:exported="false">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/authenticator"/>
</service>
</application>
</manifest>
I tried to create a service and also reference in my manifest
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.company.demo.account.DEMOACCOUNT"
android:icon="#drawable/ic_launcher"
android:smallIcon="#drawable/ic_launcher"
android:label="qualquer"/>
You cannot use the account manager to setup a new account on the Google server. It can only be used for login.
The Setup application in Android also has no API available for setting up a new account. The only real way would be to reverse engineer their application code and try to inject values. It not smart and here is why:
All of this is designed this way for customer safety and Google protection. When doing this in an automated way, the customer is not agreeing to the Terms and Conditions as well as creating an account with dangerous access to user information on the device or from the device itself.
If this is 100% required, I suggest that you have the device communicate to a server you own which handles the negotiations with Google and alerts the user accordingly. Its not what you may want to hear, but this is not an advisable route.

Android Studio: Application crashes at start

my application crashes at start and I have no idea why. I'm testing it on a real device (Samsung Galaxy S3 GT-I9300). Here is the exception:
EDIT:
So, that's what I've added to onCreate():
walking.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
travel_mode = "walking";
walking.setImageResource(R.drawable.walking_sel);
biking.setImageResource(R.drawable.regular_biking);
driving.setImageResource(R.drawable.car_icon);
transit.setImageResource(R.drawable.transit_icon);
}
});
biking.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
travel_mode = "biking";
walking.setImageResource(R.drawable.walking);
biking.setImageResource(R.drawable.regular_biking_sel);
driving.setImageResource(R.drawable.car_icon);
transit.setImageResource(R.drawable.transit_icon);
}
});
Before I've added this piece of code, everything worked correctly.
And here is AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="lukssoftware.kaart" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-library android:name="com.google.android.maps" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="***" />
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name="lukssoftware.kaart.kaart_welcome"
android:screenOrientation="portrait"
android:label="kaart" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Any ideas?
Thanks.
Please post more code and there is nothing to do with manifest here post layout xml and activity code where you have defined walking and biking findViews().
Just check it out that you have defined findViewsById of both walking and biking before you are calling setOnClickListener method.
Does your application still compile successfully after deleting the two modules?
If it doesn't compile, look for the lines in your classes or xml files which have yellow or red exclamation marks. That should alert you to where the problem is coming from.
You should also take a good look at line 64 in your *welcome.java class.

GCM Android Client Not Firing WakefulService?

I have literally followed the examples for implementing GCM inside an android app and the app is receiving the messages using the following code:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp;
comp = new ComponentName(context.getPackageName(), GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
The problem is that the GcmIntentService (public class GcmIntentService extends IntentService) is never being run? Am I missing something or should it usually fire the onHandleIntent method?
In case in any way related the Manifest file is below, thanks in advance:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.diversivi.test"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19"/>
<application
android:label="#string/app_name"
android:icon="#drawable/ic_launcher">
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity
android:name=".DemoActivity"
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=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.diversivi.test" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.diversivi.test.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.diversivi.test.permission.C2D_MESSAGE" />
</manifest>
I don't see your GcmIntentService service declared in the manifest. That could be the problem.
In addition, the following line
comp = new ComponentName(context.getPackageName(), GcmIntentService.class.getName());
assumes that the GcmIntentService class is in the main package of your app (i.e. its full name is com.diversivi.test.GcmIntentService). If that's not the case, the broadcast receiver can't find the service class.

Categories

Resources