Ringer Mode Changing App doesn't work as expected - android

I made a small app that takes input from the user in the form of a TimePicker, stores it in variables, that are later used to trigger an alarm which will keep the ringer at the desired mode until required.
But everytime I try running it on the AVD, it keeps crashing whenever I press any button, either silent or vibrate.
The MainActivity.java file:
package com.example.android.implementingringermechanism;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity {
//TimePicker to take time input from user when dialog activity pops
TimePicker picker;
//Buttons to change mode to silent or vibrate
Button silentButton, vibrateButton;
//Variables to store hours and minutes chosen by user
private int hour, minute;
//AudioManager instance used to change ringer mode
private AudioManager mAudioManager;
//AlarmManager instance used to set alarm to background task
AlarmManager mgr;
//Calendar instance to manipulate time for alarm with user input
Calendar time;
//PendingIntent to start when alarm is finished
private PendingIntent pendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
picker = (TimePicker) findViewById(R.id.timePicker);
//TimePicker will show time in 24 hour mode
picker.setIs24HourView(true);
silentButton = (Button) findViewById(R.id.silentButton);
vibrateButton = (Button) findViewById(R.id.vibrateButton);
//AlarmManager instance created to set an alarm for changing ringer mode back to normal
mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
}
public void silent(View view){
if(Build.VERSION.SDK_INT >= 23){
hour = picker.getHour();
minute = picker.getMinute();
}
else {
hour = picker.getCurrentHour();
minute = picker.getCurrentMinute();
}
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(this, "Silent mode till " + hour + ":" + minute, Toast.LENGTH_LONG).show();
time.add(Calendar.HOUR, hour);
time.add(Calendar.MINUTE, minute);
mgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);
}
public void vibrate(View view) {
if(Build.VERSION.SDK_INT >= 23){
hour = picker.getHour();
minute = picker.getMinute();
}
else {
hour = picker.getCurrentHour();
minute = picker.getCurrentMinute();
}
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
Toast.makeText(this, "Vibrate mode till " + hour + ":" + minute, Toast.LENGTH_LONG).show();
time.add(Calendar.HOUR, hour);
time.add(Calendar.MINUTE, minute);
mgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);
}
}
The activity_main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MainActivity"
android:layout_gravity="center"
android:orientation="vertical"
>
<TimePicker
android:id="#+id/timePicker"
android:layout_width="273dp"
android:layout_height="368dp"
android:layout_marginLeft="40dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/silentButton"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginLeft="40dp"
android:text="#string/silentText"
android:textStyle="bold"
android:onClick="silent"/>
<Button
android:id="#+id/vibrateButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:text="#string/vibrateText"
android:textStyle="bold"
android:onClick="vibrate"
/>
</LinearLayout>
</LinearLayout>
The AndroidManifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.implementingringermechanism">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/setTime"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Dialog">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyAlarmReceiver" />
</application>
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
</manifest>
The MyAlarmReceiver.java file:
package com.example.android.implementingringermechanism;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.widget.Toast;
class MyAlarmReceiver extends BroadcastReceiver{
private AudioManager AM;
#Override
public void onReceive(Context context, Intent intent){
AM.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Toast.makeText(context, "Ringer Mode changed to Normal", Toast.LENGTH_LONG).show();
}
}
For now, the problem I'm encountering is that on app startup, the dialog box appears, but pressing any of the two buttons makes it crash.

Your code isn't working because of two reasons:
Your AudioManager is null. Add this code to your onCreate():
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
If you're testing on a device that's running Android Marshmallow or higher, you'll need to request permission from the user before you're able to set the ringer mode. You can gain that request by adding this code:
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& !notificationManager.isNotificationPolicyAccessGranted()) {
startActivity(new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS));
}

Sir if you are testing on higher android api you need to add ask administrator previlagers first
private void fornougat() {
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& !notificationManager.isNotificationPolicyAccessGranted()) {
Toast.makeText(this, R.string.permission, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(
android.provider.Settings
.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
startActivity(intent);
}
}

Related

Call network api just as activity is finishing

I have a preference screen in my application and I want to save the user preferences in the server, but I don't want any update button in the settings, I was hoping to make this update api call when the activity is finishing, maybe I can call the api in onPause(), the problem is, if the api takes more time than expected to return then I will have a network call running without an activity, which in my general knowledge is a memory leak. If I try to have this network call in the main thread and the call takes too long I will get an ANR.
How can I achieve this behaviour in my application. I am using retrofit2 with rxjava2 to make api calls.
You can create an AsyncTask for the Networking since the doInBackground() creates a background thread which you need to avoid networking on MainThread. Also, Activity stop doesn't stop the AsyncTask.
If you need a response (for example a Toast to inform user that preferences have successfully saved) use IntentService, otherwise Service. For detailed description of the differences see: Service vs IntentService.
For the implementation (with a good example) take a look at:
https://developer.android.com/guide/components/services and
https://developer.android.com/guide/components/broadcasts (for implementing broadcast receiver in order to process the result)
Here is a simple app. In Main Activity we go to SecondActivity. There we set some values, start a service to process them and finish the activity. When everything is ready, the MainActivity is updated automatically.
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.sytes.csongi.servicetest">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SecondActivity">
</activity>
<service
android:name="services.MyIntentService"
android:exported="false"
>
</service>
</application>
</manifest>
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/main_result_txt"
android:text="Test"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/main_open_intent_btn"
android:text="start"
android:layout_gravity="center"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
activity_second.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SecondActivity">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/second_edit_01_txt"
android:hint="Enter some text here"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/second_edit_02_txt"
android:hint="another text here"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/second_start_process_btn"
android:text="start processing"
android:layout_gravity="center"/>
</LinearLayout>
MainActivity.java:
package net.sytes.csongi.servicetest;
import android.content.*;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import services.MyIntentService;
public class MainActivity extends AppCompatActivity {
private static final String TAG=MainActivity.class.getSimpleName();
private BroadcastReceiver mBroadcastReceiver;
private IntentFilter mIntentFilter;
#BindView(R.id.main_open_intent_btn)
Button mOpenIntentBtn;
#BindView(R.id.main_result_txt)
TextView mResultTxt;
public static final String ACTION_MAIN_ACTIVITY = "ACTION_MAIN_ACTIVITY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mIntentFilter=new IntentFilter();
mIntentFilter.addAction(ACTION_MAIN_ACTIVITY);
mBroadcastReceiver=new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive:::: called");
String action=intent.getAction();
if(action!=null&& ACTION_MAIN_ACTIVITY.equals(action)){
processReceivedIntent(intent);
}
}
};
registerReceiver(mBroadcastReceiver,mIntentFilter);
mOpenIntentBtn.setOnClickListener(v->
{
Intent startSecondActivity=new Intent(this,SecondActivity.class);
startActivity(startSecondActivity);
});
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy:::: called, unregistering Receiver");
unregisterReceiver(mBroadcastReceiver);
}
private void processReceivedIntent(Intent intent) {
Log.d(TAG, "processReceivedIntent:::: called");
StringBuilder builder=new StringBuilder("The values recieved: \n");
String returnedString=intent.getStringExtra(MyIntentService.EXTRA_TO_PROCESS);
builder.append(returnedString);
mResultTxt.setText(builder.toString());
}
}
SecondActivity.java:
package net.sytes.csongi.servicetest;
import android.content.ContentValues;
import android.os.Bundle;
import android.support.annotation.StringDef;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import butterknife.BindView;
import butterknife.ButterKnife;
import services.MyIntentService;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import static net.sytes.csongi.servicetest.SecondActivity.ValuesToSend.EDIT_TEXT_ONE;
import static net.sytes.csongi.servicetest.SecondActivity.ValuesToSend.EDIT_TEXT_TWO;
public class SecondActivity extends AppCompatActivity {
private static final String TAG=SecondActivity.class.getSimpleName();
#BindView(R.id.second_edit_01_txt)
EditText mSecondEditOne;
#BindView(R.id.second_edit_02_txt)
EditText mSecondEditTwo;
#BindView(R.id.second_start_process_btn)
Button mStartProcess;
#Retention(RetentionPolicy.SOURCE)
#StringDef({EDIT_TEXT_ONE,
EDIT_TEXT_TWO})
public #interface ValuesToSend {
/**
* edit text key for textField_01
*/
String EDIT_TEXT_ONE = "EDIT_TEXT_ONE";
/**
* edit text key for textField_02;
*/
String EDIT_TEXT_TWO = "EDIT_TEXT_TWO";
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
ButterKnife.bind(this);
mStartProcess.setOnClickListener(v -> {
startProcess();
});
}
private void startProcess() {
Log.d(TAG, "startProcess:::: called");
finish();
}
#Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop:::: called");
ContentValues valuesToSend=new ContentValues();
valuesToSend.put(EDIT_TEXT_ONE,mSecondEditOne.getText().toString());
valuesToSend.put(EDIT_TEXT_TWO,mSecondEditTwo.getText().toString());
Log.d(TAG, "onStop:::: contentValues size="+valuesToSend.size());
Bundle toSend=new Bundle();
toSend.putParcelable(MyIntentService.BUNDLE_CONTENT_VALUES_KEY,valuesToSend);
MyIntentService.startActionProcess(this,toSend);
}
}
MyIntentService.java:
package services;
import android.app.IntentService;
import android.content.ContentValues;
import android.content.Intent;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import net.sytes.csongi.servicetest.MainActivity;
import java.util.Iterator;
import java.util.Set;
/**
* An {#link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p>
* helper methods.
*/
public class MyIntentService extends IntentService {
private static final String TAG=MyIntentService.class.getSimpleName();
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
public static final String ACTION_PROCESS = "services.action.PROCESS";
public static final String BUNDLE_TO_PROCESS="BUNDLE_TO_PROCESS";
public static final String BUNDLE_CONTENT_VALUES_KEY = "BUNDLE_CONTENT_VALUES_KEY";
public static final String EXTRA_TO_PROCESS = "EXTRA_TO_PROCESS";
public MyIntentService() {
super("MyIntentService");
Log.d(TAG, "MyIntentService:::: instantiated");
}
/**
* Starts this service to perform action Foo with the given parameters. If
* the service is already performing a task this action will be queued.
*
* #see IntentService
*/
public static void startActionProcess(Context context, Bundle bundle) {
Log.d(TAG, "startActionProcess:::: called");
Intent intent = new Intent(context, MyIntentService.class);
intent.setAction(ACTION_PROCESS);
intent.putExtra(BUNDLE_TO_PROCESS, bundle);
context.startService(intent);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "onHandleIntent:::: called");
if (intent != null) {
final String action = intent.getAction();
if (ACTION_PROCESS.equals(action)) {
final Bundle bundleToProcess = intent.getBundleExtra(BUNDLE_TO_PROCESS);
handleAction(bundleToProcess);
}
}
}
private void handleAction(Bundle bundleToProcess) {
// here we run the long process
Log.d(TAG, "handleAction:::: called");
ContentValues contentValues= bundleToProcess.getParcelable(BUNDLE_CONTENT_VALUES_KEY);
StringBuilder builder=new StringBuilder("Processed values are:\n");
int numberOfValues=contentValues.size();
Set<String> valuesKeySet=contentValues.keySet();
Iterator<String> iterator=valuesKeySet.iterator();
while(iterator.hasNext()){
builder.append(contentValues.getAsString(iterator.next())+"\n");
try{ // simulating latency
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// send result to appropriate activity
Intent resultIntent=new Intent();
resultIntent.setAction(MainActivity.ACTION_MAIN_ACTIVITY);
resultIntent.putExtra(EXTRA_TO_PROCESS,builder.toString());
sendBroadcast(resultIntent);
}
}
Hope I could help you.

Alarm Manager in android does not issue notification on time

i am trying to make a small project in android for the college where the user has the option to select time from time picker dialog and based on the time selected an notification to drink water will be issued to the user and repeated every 15 minutes.However the alarm manager used issues notification vaguely.Sometimes notification are issued on time and repeated after every 15 minutes although after midnight the notifications stop.Also sometimes there is a delay to issue the notification.Cant figure out why! Help appreciated..Here are the necessary xml and java files
activity_water.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relative"
tools:context="com.example.priyam.databaselogin.Water">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/darker_gray"
android:layout_marginTop="70dp"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="15dp">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/reminderWaterCheckbox"
android:buttonTint="#color/red"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="Remind me once at"
android:textStyle="bold"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="170dp"
android:text="09:30 AM"
android:textColor="#color/red"
android:id="#+id/textViewTime"/>
</LinearLayout>
</RelativeLayout>
water.java
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.Calendar;
public class Water extends AppCompatActivity implements View.OnClickListener {
TextView time;
CheckBox waterReminder;
int h,m;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_water);
setTitle("Water Reminder");
getId();
Toast.makeText(getApplicationContext(),"this",Toast.LENGTH_LONG).show();
}
private void getId(){
time=(TextView)findViewById(R.id.textViewTime);
waterReminder=(CheckBox)findViewById(R.id.reminderWaterCheckbox);
time.setOnClickListener(this);
}
private void showDialog(){
TimePickerDialog timePickerDialog = new TimePickerDialog(this,
new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
h=hourOfDay;
m=minute;
Calendar calendar=Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,h);
calendar.set(Calendar.MINUTE,m);
Intent intent=new Intent(getApplicationContext(),Notification_receiver.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(getApplicationContext(),100,intent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_FIFTEEN_MINUTES,pendingIntent);
time.setText(h+":"+m);
}
}, h, m, false);
timePickerDialog.show();
}
#Override
public void onClick(View v) {
showDialog();
}
}
Notification_receiver.java
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
public class Notification_receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent1=new Intent(context,DashBoard.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent=PendingIntent.getActivity(context,100,intent1,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder=new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.logo)
.setContentTitle("Hitfit")
.setContentText("Its time you gulped a glass of water!Stay hydrated,stay fit!")
.setAutoCancel(true);
builder.setVibrate(new long[] { 1000, 1000});
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(alarmSound);
notificationManager.notify(100,builder.build());
}
}
Minnimum sdkVersion used is 18
Stuck on this since days.Thank you!
In the documentation of AlarmManager, you can see the following notice :
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
I think you are in this case actually, and your alarms aren't exact because that's how the system keeps battery as of API 19.

Group different notifications in same stack

I have a simple app that generates notifications on button Click. I also have an editText so that the content Text is typed by the user. I have two buttons that generates two different notifications. My requirement is that on every button click there should be only one notification generated and the rest should be in the notification stack. I have tried using notification setGroup property but the method doesn't seem to work. I have attached my code below for further reference.
Main Activity(Java file):-
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.TaskStackBuilder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.NotificationCompat;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private static final String GROUP_NOTIFICATIONS="group_notifications";
NotificationCompat.Builder notification;
NotificationCompat.Builder notification1;
PendingIntent pIntent;
NotificationManager manager,manager1;
Intent resultIntent;
Button button,button1;
EditText editText;
int a=0,b=100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText= (EditText) findViewById(R.id.edittext);
button= (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startNotification();
}
});
button1= (Button) findViewById(R.id.button2);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Notifications();
}
});
}
public void buttonClick(View view)
{
startNotification();
}
public void startNotification()
{
// Intent intent=new Intent(MainActivity.this,MyService.class);
// intent.putExtra("id",Integer.toString(a));
// startService(intent);
// PendingIntent pendingIntent=PendingIntent.getService(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
String str=editText.getText().toString();
notification=new NotificationCompat.Builder(this);
notification.setContentTitle("ABC");
notification.setContentText(str);
notification.setTicker("New Message Arrived");
notification.setSmallIcon(R.mipmap.ic_launcher);
notification.setGroup(GROUP_NOTIFICATIONS);
notification.setGroupSummary(true);
int num=0;
// notification.setNumber(++num);
Uri uri=RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notification.setSound(uri);
manager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(a,notification.build());
a++;
}
public void Notifications()
{
String str=editText.getText().toString();
notification1=new NotificationCompat.Builder(MainActivity.this);
notification1.setContentTitle("ABC");
notification1.setContentText(str);
notification1.setTicker("New Message Arrived");
notification1.setSmallIcon(R.mipmap.ic_launcher);
notification1.setGroup(GROUP_NOTIFICATIONS);
notification1.setGroupSummary(true);
int num=0;
// notification1.setNumber(++num);
Uri uri=RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notification1.setSound(uri);
manager1= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager1.notify(a,notification1.build());
a++;
}
}
activity_main.xml(XML file)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.pratik.stacked.MainActivity">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/edittext"
android:textColor="#color/colorPrimary"
android:textSize="20sp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Stacked Notification"
android:id="#+id/button"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Stacked notifiction 1"
android:id="#+id/button2"
android:layout_above="#+id/button"
android:layout_alignLeft="#+id/button"
android:layout_alignStart="#+id/button"
/>
</RelativeLayout>
AndroidManifest.xml(Manifest file)
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
This is all about setting properly flags.
FLAG_GROUP_SUMMARY
The problem is that you are incrementing (a++) the notification ID:
manager1.notify(a,notification1.build());
a++;
If you want to update an existing notification you should call notify with the notification ID that you want to update. You can refer to the documentation
If you are on Android >= 4.1 you can use expanded layouts. Take into account that in this case you may want to ensure compatibility following these guidelines.

how to show notification that shows up on main screen and all applications - Android

I wanna show the notification like messaging app Line, both on main screen and on any application it shows a notification box with the message in it for a seconds and disappear then.
something like this:
so what are possible ways to do this ? is it a custom Toast? or custom Dialog?
You have to create a window animation like this :
MyService.java
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
/**
* Created by darshan.mistry on 7/18/2015.
*/
public class MyService extends Service {
View mView;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
// instance of WindowManager
WindowManager mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
LayoutInflater mInflater = (LayoutInflater)
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// inflate required layout file
mView = mInflater.inflate(R.layout.abc, null);
// attach OnClickListener
mView.findViewById(R.id.someView).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// you can fire an Intent accordingly - to deal with the click event
// stop the service - this also removes `mView` from the window
// because onDestroy() is called - that's where we remove `mView`
stopSelf();
}
});
// the LayoutParams for `mView`
// main attraction here is `TYPE_SYSTEM_ERROR`
// as you noted above, `TYPE_SYSTEM_ALERT` does not work on the lockscreen
// `TYPE_SYSTEM_OVERLAY` works very well but is focusable - no click events
// `TYPE_SYSTEM_ERROR` supports all these requirements
WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
PixelFormat.RGBA_8888);
// finally, add the view to window
mWindowManager.addView(mView, mLayoutParams);
}
#Override
public void onDestroy() {
super.onDestroy();
// remove `mView` from the window
removeNow();
}
// Removes `mView` from the window
public void removeNow() {
if (mView != null) {
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.removeView(mView);
}
}
}
MyReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
* Created by darshan.mistry on 7/18/2015.
*/
public class MyReciver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, MyService.class);
context.startService(intent1);
}
}
In the manifest file, add the permission:
<!-- [My service and reciver] -->
<service
android:name=".MyService"
android:exported="true" />
<receiver android:name=".MyReciver">
<intent-filter>
<action android:name="com.tutorialspoint.CUSTOM_INTENT"></action>
</intent-filter>
</receiver>
MyService class xml file :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:background="#android:color/white">
<TextView
android:id="#+id/someView"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:layout_gravity="center"
android:background="#android:color/white"
android:gravity="center"
android:text="This is Demo"
android:textColor="#android:color/black" />
</RelativeLayout>
You have to call MyService from where you have got notification add below lines:
Intent intent = new Intent();
intent.setAction("com.tutorialspoint.CUSTOM_INTENT");
sendBroadcast(intent);
This is a simple example so you have got ideas how to implement notification like line app.
You can create a custom dialog with this permission
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Follow this answer for more details.

Continous notification after 2 minutes android

I want to show continuous notifications in my application.
Currently I am able to raise notification automatically after 4sec but what I want is it should continuously raise after specific time interval.
Following is my code.
my xml file is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<Button android:id="#+id/notify"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Raise a notification"
android:onClick="notifyMe"
/>
<Button android:id="#+id/cancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Clear the notification"
android:onClick="clearNotification"
/>
</LinearLayout>
this is my activity file
package com.vimaltuts.android.notificationexample;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class NotificationExampleActivity extends Activity {
private static final int NOTIFY_ME_ID=1987;
private int count=0;
private NotificationManager mgr=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mgr=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Timer timer = new Timer();
timer.schedule(new TimerTask()
{
public void run()
{
View v = new View(getApplicationContext());
notifyMe(v);
}},4000);
}
#SuppressWarnings("deprecation")
public void notifyMe(View v)
{
#SuppressWarnings("deprecation")
Notification note=new Notification(R.drawable.stat_notify_chat,"Status message!",System.currentTimeMillis());
PendingIntent i=PendingIntent.getActivity(this,0,new Intent(this, NotificationMessage.class),0);
note.setLatestEventInfo(this, "New Email","Unread Conversation", i);
note.number=++count;
note.vibrate=new long[] {500L, 200L, 200L, 500L};
note.flags|=Notification.FLAG_AUTO_CANCEL;
mgr.notify(NOTIFY_ME_ID, note);
}
public void clearNotification(View v) {
mgr.cancel(NOTIFY_ME_ID);
}
}
Please tell me where should I need to have additional code if any?
Also is it possible with service..how?
i tried following code foe test purpose but it did't work...can anyone tell me where i goes wrong
following is my activity code
Intent i= new Intent(NotificationExampleActivity.this,NotificationService.class);
PendingIntent pi=PendingIntent.getService(NotificationExampleActivity.this, 0, i, 0);
AlarmManager alarmMgr=(AlarmManager)getSystemService(ALARM_SERVICE);
alarmMgr.cancel(pi);
alarmMgr.setRepeating(alarmMgr.ELAPSED_REALTIME_WAKEUP, System.currentTimeMillis(),(10*1000), pi);
Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
And following is my broadcast reciver
Toast.makeText(context, "Repeating Alarm worked.", Toast.LENGTH_LONG).show();
i want to display msg="Repeating Alarm worked" after some time intervel
Try using an AlarmManager along with the notification.
You can set a repeating alarm in your Activity. Then create a class that extends the BroadcastReceiver. Override the onReceive method where in you can write the code for your notification.
A tutorial on this is explained very well over here.

Categories

Resources