I'm attempting to use the NotificationCompat.Builder class in my app. The following code runs perfectly fine on an ICS phone, but not Gingerbread. From my understanding, doesn't the support library allow access to the Builder from phones as low as API level 4? Am I doing something fundamentally wrong?
public class MainActivity extends Activity implements OnClickListener {
NotificationCompat.Builder builder;
NotificationManager nm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
builder = new NotificationCompat.Builder(this);
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
builder.setContentTitle("Test Notification")
.setContentText("This is just a test notification")
.setTicker("you have been notified")
.setSmallIcon(R.drawable.ic_stat_example)
.setWhen(System.currentTimeMillis());
findViewById(R.id.btn_notify).setOnClickListener(this);
}
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(arg0.getId() == R.id.btn_notify){
nm.notify(1, builder.build());
}
}
}
You have to supply the Intent which will be triggered when the notification is clicked. Otherwise, the notification will not be displayed on Gingerbread.
If you do not want to start the Activity when the notification is clicked, you can just pass an empty Intent as following.
Intent intent = new Intent();
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
builder.setContentTitle("Test Notification")
.setContentText("This is just a test notification")
.setTicker("you have been notified")
.setSmallIcon(R.drawable.ic_stat_example)
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingIntent); // add this
Related
I have follow this guide to setup push notification in my Xamarin Forms app.
I have an app with two activity,
one splash activity
Activity(Theme = "#style/SplashTheme",
MainLauncher = true, ScreenOrientation = ScreenOrientation.Portrait, NoHistory = true)]
public class SplashAct: Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
StartActivity(typeof(MainActivity));
Finish();
}
}
and the MainActivity
[Activity(
ClearTaskOnLaunch = false,
FinishOnTaskLaunch = false,
Theme = "#style/MainTheme",
LaunchMode = LaunchMode.SingleTask,
ScreenOrientation = ScreenOrientation.Portrait,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public partial class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener
in the main activity I have override the OnNewIntent method
protected override void OnNewIntent(Intent intent)
{
base.OnNewIntent(intent);
ProcessNotificationActions(intent);
}
and I have tried to send a notification using a web api published on Azure with this body:
{
"text": "Test msg",
"action": "action_a"
}
on device the text is correctly shown, but when the code reach the OnNewIntent method the intent has not extras so I lost the "action" value.
How can I solve this?
NB. I can't use LaunchMode = LaunchMode.SingleTop otherwise the OnNewIntent is not called, the OnCreate is called and the app shows a blank screen.
This happens only if the application is in background or closed. If it is in foreground all works fine.
Attached a sample, a video and info to make the POSTMAN\RESTER request.
Archive.zip
Your SplashAct is set to be the MainLauncher which will be fired up when your push notification is tapped. The Intent recieved there first will not automatically pass the extras on when it launches MainActivity. You can manually transfer them over when you call StartActivity in your SplashAct:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
var intent = new Intent(Application.Context, typeof(MainActivity));
intent.PutExtras(Intent);
StartActivity(intent);
Finish();
}
I am currently trying to build a new app (complete Novice) I have run into a strange issue on the login page.The sign up process works fine connects to firebase and returns to the login screen, then allows you to login and goes to the next activity. The problem occurs when you reload the app and use the details to re-login the login button does not work until you go into the sign up activity and come out of it then the login button works fine and allows you to sign in.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Button button = findViewById(R.id.signupbtn);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
openSignupActivity();
}
});
}
private void openSignupActivity() {
Intent intent = new Intent(LoginActivity.this, SignupActivity.class);
startActivity(intent);
setContentView(R.layout.activity_login);
LoginEmail = findViewById(R.id.LoginEmail);
LoginPassword = findViewById(R.id.LoginPassword);
Loginprogressbar = findViewById(R.id.Loginprogressbar);
mAuth = FirebaseAuth.getInstance();
findViewById(R.id.Loginbtn).setOnClickListener(this);
if conditions between
if(task.isSuccessful()){
Toast.makeText(getApplicationContext(),"Login Successful",Toast.LENGTH_SHORT).show();
finish();
startActivity(new Intent(LoginActivity.this,MainActivity.class));
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.Loginbtn:
Loginuser();
break;`enter code here`
I've created a test app to understand how to call the native gallery, select an image and display it on an imageView.
1st test
I had a simple setup. One activity and a fragment(residing within that activity) that has a button(calls gallery intent) and an imageView for the selected image. This worked perfectly.
2nd test
Changed the setup a bit by adding another activity and a tab host to the main activity. This new empty activity would be the launching activity and it's only purpose was to switch to the main activity that holds the fragment that calls the gallery intent. Everything works fine until I select the image from the gallery. Once the image is selected, it doesn't go back to the my test app. It's like a weird soft crash. Logcat doesn't display any errors so it's a bit hard to troubleshoot. I also placed a breakpoint on each line of the OnActivityResult override but they never hit.
I was hoping somebody would shed light on this matter.
SDK version is 23 and build tools is 23.0.3
Heres what I got so far:
Main2Activity(Launching activity)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ActivityConfig.CreateActivity(MainActivity.class, this, true);
}
In case you were wondering what CreateActivity does:
public static void CreateActivity(Class activityClass, Context context,
boolean finishPreviousActivity)
{
Intent intent = new Intent(context, activityClass);
if (finishPreviousActivity)
{
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
}
context.startActivity(intent);
}
MainActivity(I only use the third position on the tabhost. That's where the fragment is)
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TabHost tabHost = (TabHost) findViewById(R.id.tabHost);
tabHost.setup();
tabHost.addTab(Tabs.CreateTab("T1", R.id.tabFrag2, tabHost));
tabHost.addTab(Tabs.CreateTab("T2", R.id.tabFrag3, tabHost));
tabHost.addTab(Tabs.CreateTab("T3", R.id.tabFrag, tabHost));
tabHost.setCurrentTab(2);
}
Fragment
private ImageView imageView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_blank, container, false);
Button button = (Button)view.findViewById(R.id.Btn);
imageView = (ImageView)view.findViewById(R.id.Img);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(intent, 100);
}
});
return view;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100)
imageView.setImageURI(data.getData());
}
After much trail an error I noticed that after selecting an image it was going back to the launching activity, but not through onCreate or it's overridden onActivityResult. It was going through onResult. My conclusion was redesign the whole interface in a way that only one activity was required
The push notification clears when the user taps on the notification to open app. However if the user goes and opens the app, the push notification is still there. How can I get rid of the notification? I can't seem to find anywhere in the documentation that addresses this.
Thanks a lot in advance
I did some digging as I too had this problem, and it looks like a bug in the Push Plugin. Basically they added the removal code to the pause event instead of the resume event.
You just have to change the code in src/android/com/plugin/gcm/PushPlugin.java
from:
#Override
public void onPause(boolean multitasking) {
super.onPause(multitasking);
gForeground = false;
final NotificationManager notificationManager = (NotificationManager) cordova.getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
#Override
public void onResume(boolean multitasking) {
super.onResume(multitasking);
gForeground = true;
}
to:
#Override
public void onPause(boolean multitasking) {
super.onPause(multitasking);
gForeground = false;
}
#Override
public void onResume(boolean multitasking) {
super.onResume(multitasking);
gForeground = true;
final NotificationManager notificationManager = (NotificationManager) cordova.getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
This will create a more standard behaviour, where the notifications will be removed on app resume (instead of on pause). Note though, I haven't fully tested the effects on the internal app messages yet, which may require more changes.
I'm learning Retrofit and RxJava and I'v created test to connect github:
public class GitHubServiceTests {
RestAdapter restAdapter;
GitHubService service;
#Before
public void setUp(){
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
restAdapter = new RestAdapter.Builder()
.setEndpoint("https://api.github.com")
.setConverter(new GsonConverter(gson))
.build();
service = restAdapter.create(GitHubService.class);
}
#Test
public void GitHubUsersListObservableTest(){
service.getObservableUserList().flatMap(Observable::from)
.subscribe(user -> System.out.println(user.login));
}
when I execute test, I see nothing in my console. But when I execute another test
#Test
public void GitHubUsersListTest(){
List<User> users = service.getUsersList();
for (User user : users) {
System.out.println(user.login);
}
it works, and I see user's logins in my console
Here is my Interface for Retrofit:
public interface GitHubService {
#GET("/users")
List<User> getUsersList();
#GET("/users")
Observable<List<User>> getObservableUserList();
}
where I'm wrong?
Because of the asynchronous call your test completes before a result is downloaded. That's typical issue and you have to 'tell' test to wait for the result. In plain java it would be:
#Test
public void GitHubUsersListObservableTest(){
CountDownLatch latch = new CountDownLatch(N);
service.getObservableUserList()
.flatMap(Observable::from)
.subscribe(user -> {
System.out.println(user.login);
latch.countDown();
});
latch.await();
}
Or you can use BlockingObservable from RxJava:
// This does not block.
BlockingObservable<User> observable = service.getObservableUserList()
.flatMap(Observable::from)
.toBlocking();
// This blocks and is called for every emitted item.
observable.forEach(user -> System.out.println(user.login));