Open main-activity one time - java

For my news-reader app, I made a widget. Using the widget it is possible to start the news-app. But if the user goes back to the home screen, with the back button, there still is an instance of the application. So if the user goes the applications-list (all the app's) and start the news-app again. There are 2 instances of the news app :S For closing the app, the users needs to push 2 times on the back button (because you see 2 times the same app). Can I do anything about it?
Here my code:
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
Intent configIntent = new Intent(context, Main.class);
PendingIntent configPendingIntent = PendingIntent.getActivity(context, 0, configIntent, 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
remoteViews.setOnClickPendingIntent(R.id.headlinesBox, configPendingIntent);
// Tell the widget manager
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}

It seems that you have to add to the manifest:
<activity android:name=".Main"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>

You can set true on android:clearTaskOnLaunch activity attribute in the Manifest file.
It should always close all the extra Activities and start the App from the first Activity.

Related

Sending data from notification click to child activity

I have two activities, one called SplashActivity which is the Launcher and the main activity of the app and the second called MainActivity which is the child activity of SplashActivity, based on some event i have a notification created and when notification click i want the MainActivity to open and send data in extra.
My problem is i have tried every solution pops in front of me nothing worked.
this is my current code:
NotificationChannel channel = new NotificationChannel(String.valueOf(12), name, NotificationManager.IMPORTANCE_HIGH);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());
notificationManagerCompat.createNotificationChannel(channel);
// Create an Intent for the activity you want to start
Intent notifyIntent = new Intent(getApplicationContext(), SplashActivity.class);
notifyIntent.putExtra("notify", "notify");
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Create the PendingIntent
PendingIntent notifyPendingIntent = PendingIntent.getActivity(
this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, String.valueOf(12))
.setSmallIcon(R.drawable.logo)
.setContentTitle(title)
.setContentText(body)
.setVibrate(new long[]{0, 100, 1000, 300})
.setAutoCancel(true)
.setContentIntent(notifyPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH);
Notification notification = builder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// notificationId is a unique int for each notification that you must define
notificationManagerCompat.notify(12, notification);
two activities declaration in manifest:
<activity
android:name=".home.activities.MainActivity"
android:parentActivityName=".SplashActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".SplashActivity"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
any one what is the solution? and why my current code is not working?
please help me i been working two days for this to work.
You forgot putExtra to intent when start MainActivity, you only show log. Try this
Intent i = new Intent(this, destinationActivity);
i.putExtras(getIntent());
Log.e(TAG, "navigateTo: " + getIntent().getStringExtra("notify"));
startActivity(i);
finish();
after a while trying different solutions i didn't know what the problem is.
but what i did is i used this code:
if (getIntent().getExtras() != null)
getIntent().getExtras().keySet().iterator().forEachRemaining(new Consumer<String>() {
#Override
public void accept(String s) {
Log.e(TAG, "accept: " + s);
}
});
to print out the extras keys i have when the activity opens from notification i saw a unique set of keys and i used one of them as trigger for specific action when it opens from notification.

how can i do unit testing for APIs?

i`am new to unit testing and i have this task to write unit testing for Post API i have only the end point and api body i read a lot in google but i could not figure out how to start , any help ?
You must create a intent, fill it with data if needed, like the data extracted from the QR code and then call startActivity.
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle b = new Bundle();
b.putInt("key", 1); //Your id
intent.putExtras(b); //Put your id to your next Intent
startActivity(intent);
finish();
I put an int in the bundle but it could be anything that implements Serializable.
You can reach direct on required screen with that pages’s activity (as shown Splash screen in below example). You can launch activity with below method.
public static void launchActivity(Activity activityName)
{
((AndroidDriver<MobileElement>) driver).startActivity(activityName);
}
How you can call this function
Suppose you have below app package and activity (its for example but you have to use for your app)
String appPackage ="my.app.helloworld";
String appActivity = "my.app.helloworld".common.activity.SplashScreen";
launchActivity(new Activity(appPackage, appActivity));
You need to set android:exported="true" in your AndroidManifest.xml file to resolve error java.lang.SecurityException
<activity
android:name="com.dsquares.lucky/.screens.mainscreens.Wallet.WalletPayment.AddFundsActivity"
android:label="wallet"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" >
</action>
</intent-filter>
</activity>

Launch a new activity from notification bar when that same activity is currently being used

I launch a specific Activity from a button in notification. If I'm not currently opening that specific Activity, it will launch the Activity as a new one. However, when I'm opening that specific Activity, scroll down the notification then click that button, it would do nothing as the Activity already opened. I need to open it as a new one as new values will be passed into it. I could use SharedPreferences to do that but I prefer not to. Please help
intent = new Intent(context,AppReport.class);
intent.putExtra("name",packageInstallName); //this does not get send over
intent.putExtra("version",packageInstallVersion);
PendingIntent testing = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
setOnClickPendingIntent(buttons[1],testing);
This is how the activity is launched from notification bar. I tried FLAG_UPDATE_CURRENT for the flag but also didn't work.
Make your Activity as singleTop
<activity
android:name=".AppReport"
android:configChanges="screenSize|keyboard|orientation|screenSize"
android:label="#string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar"
android:windowSoftInputMode="stateHidden"/>
intent = new Intent(context,AppReport.class);
intent.putExtra("name",packageInstallName); //this does not get send over
intent.putExtra("version",packageInstallVersion);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent testing = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Override onNewIntent(Intent intent) in Activity.
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//Do your stuff
}

Android broadcast not received from widget

I Have a widget that upon button press I send broadcast to service. But I am not receving any broadcast in my onReceive().
My intention is basically on widget button click, it tellls service to perform some action.
But I am unable to receive any broadcast from widget in service.
Here is my widget code -
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews remoteViews;
ComponentName componentName;
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
componentName = new ComponentName(context, MyWidgetProvider.class);
remoteViews.setOnClickPendingIntent(R.id.play,getPendingSelfIntent(context, "PLAY",componentName));
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews;
ComponentName componentName;
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
componentName = new ComponentName(context, MyService.class);
if (intent.getAction().equals("PLAY")) {
Log.d("hi","PLAY0");
remoteViews.setOnClickPendingIntent(R.id.engine_lock_unlock,getPendingSelfIntent(context,"PLAY",componentName));
serviceIntent = new Intent(context,MyService.class);
serviceIntent.setAction("PLEASE_PLAY");
Log.d("hi","PLAY1");
context.sendBroadcast(serviceIntent);
}
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
protected PendingIntent getPendingSelfIntent(Context context, String action, ComponentName componentName) {
Intent intent = new Intent(context, MyWidgetProvider.class);
intent.setAction(action);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, componentName);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
In MyService,
public class ServiceWidgetReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("hi","PLAY2");
if (intent.getAction().equals("PLEASE_PLAY")) {
}
}
}
My MAnifest looks like this -
<receiver android:name=".widget.MyWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/homescreen_widget_preview" />
</receiver>
<receiver android:name=".service.MyService$ServiceWidgetReceiver" />
I only get the logs -
PLAY0
PLAY1
Why I dont get my broadcast???
Seams that your receiver has no intent-filter provided. Try to add this in your mainfest file:
<receiver android:name=".service.MyService$ServiceWidgetReceiver">
<intent-filter>
<action android:name="PLEASE_PLAY" />
</intent-filter>
</receiver>
I assume that you have implement the action in intent-filter like Myon said, but the still no broadcast to the onReceive. you may try this:
protected PendingIntent getPendingSelfIntent(Context context, String action, ComponentName componentName) {
Intent intent = new Intent(context, MyWidgetProvider.class);
intent.setAction(action);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, componentName);
//this line replace the original
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Actually, i have facing the similar problem yesterday that my widget work fine on my android 5.1 phone. However, I find it cannot perform click on android 7.0 sony phone. I still trying to find out whether is the sony phone os problem or android 7.0 or after problem because after the upgrade of the 7.0 or after, there is so many different issues appeared as they changed quite a lot in the API. Anyway, I used the PendingIntent.FLAG_UPDATE_CURRENT solved the problem I have on 7.0
I just think will directly register the receiver class to manifest like this be work. The service binded doesnt directly affect the receive, as the only thing affect the receiver is context. So, maybe just the receive class is enough.
<receiver android:name="packageName.ServiceWidgetReceiver">
<intent-filter>
<action android:name="PLEASE_PLAY" />
</intent-filter>
</receiver>
I found out the mistake I was doing. I had to registerreceiver and unregister it in Service itself rather in Manifest.
This worked for me.

How can I keep my app's notification displayed when my app is updated on Google Play store?

My app has a function of set-notification. Here is my code.
#SuppressWarnings("deprecation")
public static void setNotification(Context _context) {
NotificationManager notificationManager =
(NotificationManager) _context.getSystemService(Context.NOTIFICATION_SERVICE);
int icon_id = R.drawable.icon;
Notification notification = new Notification(icon_id,
_context.getString(R.string.app_name), System.currentTimeMillis());
//
Intent intent = new Intent(_context, MainActivity.class);
notification.flags = Notification.FLAG_ONGOING_EVENT;
PendingIntent contextIntent = PendingIntent.getActivity(_context, 0, intent, 0);
notification.setLatestEventInfo(_context,
_context.getString(R.string.app_name),
_context.getString(R.string.notify_summary), contextIntent);
notificationManager.notify(R.string.app_name, notification);
}
This code works fine. If my app is closed, notification keeps displayed.
But even if notification was set, the notification is cancelled when user will update my app version by Google Play store.
I know that...
The notification is cancelled when my app is uninstalled.
In fact an update is "uninstall and install".
How can I keep displayed when my app version is updated?
If I understood right you want displaying a notification after updating.
So you can implement receiver that listens updating of app or rebooting of device and shows notification again.
add to you manifest:
<receiver
android:name=".UpdatingReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
and implement receiver:
public class UpdatingReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()) || Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) {
// check is need to show notification
}
}

Categories

Resources