Trouble setting off notifications with broadcast receiver - Android Studio

So I am building a program with a notification that activates 3 hours after the activity is stopped (for testing purposes I am currently using minutes). This is what my main activity looks like...
Code:
Override
public void onStop() {
super.onStop();
Calendar calendar = Calendar.getInstance();
int alarmTime = (calendar.get(Calendar.MINUTE)) + 3;
calendar.set(Calendar.MINUTE,alarmTime);
Intent intent3 = new Intent(getApplicationContext(),timeReceiver.class);
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(getApplicationContext(),100,intent3,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent3);
}
@Override
protected void onRestart() {
super.onRestart();
//this.onCreate(null);
}
This is what my broadcast receiver class looks like...
Code:
public class timeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager =(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent repeating_intent = new Intent(context, RepeatingActivity.class);
repeating_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context,100,repeating_intent,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentIntent(pendingIntent);
builder.setSmallIcon(android.R.drawable.arrow_up_float);
builder.setContentTitle("Timer Notification");
builder.setContentText("blaaah blaaah blah");
builder.setAutoCancel(true);
notificationManager.notify(100,builder.build());
}
}
3 minutes after running the stop code the timer is activated the way it's supposed to, however my problem is that if the code is executed a second time within this 3 minute period - then no notification is pushed at all. My hope is that the alarm would reset and trigger 3 minutes after the last execution of the onStop() method, but it doesn't. I don't really understand why it doesn't, if anyone could give me insight/ a possible solution I would be grateful. Also the SDK version is 24.

I've already worked on a alarm scheduler (notification) just yesterday.
So here comes my working code (you can find it in github / binogure-studio):
Code:
public void schedule_local_notification(String title, String content, int delay, int notification_id) {
// delay is after how much time(in millis) from current time you want to schedule the notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, activity.getPackageName() + CHANNEL_ID)
.setContentTitle(title)
.setContentText(content)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_stat_name)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
Intent intent = new Intent(context, Godot.class);
PendingIntent intentActivity = PendingIntent.getActivity(context, notification_id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
builder.setContentIntent(intentActivity);
Notification notification = builder.build();
Intent notificationIntent = new Intent(context, LocalNotificationReceiver.class);
notificationIntent.putExtra(LocalNotificationReceiver.NOTIFICATION_ID, notification_id);
notificationIntent.putExtra(LocalNotificationReceiver.NOTIFICATION, notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notification_id, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
long futureInMillis = SystemClock.elapsedRealtime() + delay * 1000;
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
}
public void cancel_local_notification(int notification_id) {
try {
Intent intent = new Intent(context, LocalNotificationReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notification_id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
} catch (Exception ex) {
Log.w(TAG, "Cannot show local notification: " + ex.getMessage());
}
}

Related

Hooking a method from background service

Hi,
I'm trying to hook some of the Android APIs in my module. I have a simple app consists of two activities (MyActivity, DisplayMessageActivity) and one service (LocationService). "MyActivity" starts "LocationService" using the following code:
Intent intent = new Intent(getApplicationContext(), LocationService.class);
startService(intent);
"MyActivity" can also start "DisplayMessageActivity" by pressing a button using the following code:
Intent intent = new Intent(this, DisplayMessageActivity.class);
startActivity(intent);
In the "LocationService", I register a GPS location listener at the start of service, which will update the "DisplayMessageActivity" upon change in the location or provider status as follows:
public int onStartCommand(Intent intent, int flags, int startId) {
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
Intent intent1 = new Intent(getApplicationContext(), DisplayMessageActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
}
public void onStatusChanged(Location location) {
Intent intent1 = new Intent(getApplicationContext(), DisplayMessageActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
}
public void onProviderEnabled(Location location) {
Intent intent1 = new Intent(getApplicationContext(), DisplayMessageActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
}
public void onProviderDisabled(Location location) {
Intent intent1 = new Intent(getApplicationContext(), DisplayMessageActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, locationListener);
return Service.START_NOT_STICKY;
}
I hooked the method "startActivity" in my module as follows:
XposedHelpers.findAndHookMethod("android.app.Activity", lpparam.classLoader, "startActivity", android.content.Intent.class, new XC_MethodHook() {
@override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Intent intent = (Intent) param.args[0];
String destination = intent.getComponent().getClassName().split(lpparam.packageName+".")[1];
XposedBridge.log("(Intent,"+destination+")");
}
});
The module successfully logs the invocation of "startActivity" when I press the button (starting "DisplayMessageActivity" from "MyActivity"). But when "startActivity" is invoked from the service, the module does not log the invocation. I'm new to Xposed and I'm not sure why this is happening. Is this because the "startActivity" is called from a background service? What can I do to resolve the issue?
I really appreciate your help
You can go to rovo89's Github for help, he is keen at helping other's development.
You are hooking on startActivity method of android.app.Activity class.
This method is specific for Activity class only as it overrides startActivity from super class (ContextWrapper and Context which is abstract). Calling startActivity within Service class is like calling completely different method that's why your hook won't work here.
To be able to cover both cases, you will have to hook on lower level in class hierarchy.
Probably the best would be to hook onto startActivity(Intent intent, Bundle bundle) of ContextWrapper class as it is sure all calls made from either Activity or Service will go this path.
So
Code:
XposedHelpers.findAndHookMethod("android.content.ContextWrapper", lpparam.classLoader, "startActivity", Intent.class, Bundle.class, new XC_MethodHook() {
....
}

Handler android

Dear People,
I´m working on a app to control my robot with bluetooth.
So i made a thread to handle the bluetooth device, and a handler to read the information in the Gui thread.
(See code below)
The problem is that i´m not able to print the information to the textview in the handler.
When i print somthing to the textview in de onCreate function, everythings works fine, but when i print something to the textview in the handler, nothing happens.
There are also no errors or something like that.
I know that the handler function is called, because the receive messages are printed well in the log.d.
I hope that there is anyone who can help me.
thanks in advance.
Tom
public class InteractionActivity extends Activity {
private ConnectThread mConnectThread;
private interface MessageConstants
{
public static final int MESSAGE_READ = 0;
public static final int MESSAGE_WRITE = 1;
public static final int MESSAGE_TOAST = 2;
}
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_interaction);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
BluetoothDevice device = getIntent().getExtras().getParcelable("btdevice");
((TextView) findViewById(R.id.textView5)).setText("Hallo"); // works fine, print correct to the screen
mConnectThread = new ConnectThread(device);
mConnectThread.start();
}
private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
byte[] writeBuf = (byte[]) msg.obj;
int begin = (int)msg.arg1;
int end = (int)msg.arg2;
String writeMessage = new String(writeBuf);
writeMessage = writeMessage.substring(begin, end);
((TextView) findViewById(R.id.textView5)).setText("Hallo1111"); //Nothing happens
Log.d(TAG, writeMessage); //is printed fine in the log
}
};
private class ConnectThread extends Thread {
etc ............

Difficulties on displaying another full screen activity for alarm clock app

I'm a student learning programming in Android Studio and I met some difficulties when developing my Alarm clock project. I've done lots of experiments and research in my code but still I couldn't find the solution. I wanted to try to make a normal alarm that is when the alarm is activated, display another full screen activity to remind the user. I don't want my alarm app to just ring and toast notification. I want it to also display a screen.
Here is my main code:
Code:
import java.util.Calendar;
import static android.R.id.message;
import static android.provider.AlarmClock.EXTRA_MESSAGE;
public class MainActivity extends AppCompatActivity
{
TimePicker alarmTimePicker;
PendingIntent pendingIntent;
AlarmManager alarmManager;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmTimePicker = (TimePicker) findViewById(R.id.timePicker);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
}
// Toggle button
public void OnToggleClicked(View view)
{
long time;
if (((ToggleButton) view).isChecked())
{
Toast.makeText(MainActivity.this, "Activated", Toast.LENGTH_SHORT).show();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute() + 1);
Intent intent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
time=(calendar.getTimeInMillis()-(calendar.getTimeInMillis()%60000));
if(System.currentTimeMillis()>time)
{
if (calendar.AM_PM == 0)
time = time + (1000*60*60*12);
else
time = time + (1000*60*60*24);
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, time, 120000, pendingIntent);
}
else
{
Toast.makeText(MainActivity.this, "OFF", Toast.LENGTH_SHORT).show();
alarmManager.cancel(pendingIntent);
}
}
}
i will comment my manifest

Bottom Navigation Bar issue

Hi, I'm new to java and Android Studio developing. So I created a BottomNavigationView but I have problems when I try to switch between fragments. That's the code:
Code:
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment memo = new MemoFragment();
Fragment archive = new ArchiveFragment();
Fragment settings = new SettingsFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch (item.getItemId()) {
case R.id.navigation_archive:
fragmentTransaction.replace(R.id.content_frame, archive);
fragmentTransaction.commit();
return true;
case R.id.navigation_memo:
fragmentTransaction.replace(R.id.content_frame, memo);
fragmentTransaction.commit();
return true;
case R.id.navigation_settings:
fragmentTransaction.replace(R.id.content_frame, settings);
fragmentTransaction.commit();
return true;
}
return false;
}
};
When I tap on any item in the Bottom Navigation Bar the app crashes. Can someone help me please?

New to Forum, New to Android

Hey ladies and gents,
I'm new to your forums, seems it will be a helpful resource as I undertake this new project. I'm not new to programming, but i'm rusty. About 20 years ago I started with Qbasic, in high school i moved on to Visual Studio and C++. But I have been out of it for awhile now.
I started learning a little python to help my dad with his own program. But Decided I wanted to use Android Studio for my own. I have already started looking into tutorials, but have yet to see some information I am looking for. ( Or just don't recognize due to inexperience )
Traditionally, whats best to use for a multiscreen App? I am currently running windows in Fragments. I have a sidescreen that pops out with a menu button (works), windows slide out with options ( works ), when you select the option the window slides away (works) and it brings up the fragment so you can fill in forms (works.)
Inside my Fragments java file I have this
public class ac extends Fragment {
private EditText od_input;
private EditText sp_input;
private EditText hp_input;
private EditText sl_input;
private EditText hl_input;
private EditText return_input;
private EditText vent_input;
private TextView diag_output;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public ac() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment ac.
*/
// TODO: Rename and change types and number of parameters
public static ac newInstance(String param1, String param2) {
ac fragment = new ac();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
EditText odtext;
EditText idtext;
EditText sptext;
EditText hptext;
EditText sltext;
EditText hltext;
EditText returntext;
EditText venttext;
@override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_ac, container, false);
// NOTE : We are calling the onFragmentInteraction() declared in the MainActivity
// ie we are sending "Fragment 1" as title parameter when fragment1 is activated
if (mListener != null) {
mListener.onFragmentInteraction("Air Conditioning");
}
// Here we will can create click listners etc for all the gui elements on the fragment.
// For eg: Button btn1= (Button) view.findViewById(R.id.frag1_btn1);
// btn1.setOnclickListener(...
//odtext = view.findViewById(R.id.odtext);
//idtext = (EditText) findViewById(R.id.idtext);
//sptext = view.findViewById(R.id.sptext);
//hptext = view.findViewById(R.id.hptext);
//sltext = view. findViewById(R.id.sltext);
//hltext = view.findViewById(R.id.hltext);
//returntext = view.findViewById(R.id.returntext);
//venttext = view.findViewById(R.id.venttext);
//TextView diagtext = view.findViewById(R.id.diagtext);
//diagtext.setText((CharSequence) odtext);
return view;
}
@override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// NOTE : We changed the Uri to String.
void onFragmentInteraction(String title);
}
}
Firstly, yes there is a lot of useless crapification going on. Was running different experiments and have not fully cleaned up yet.
But, as people type in the field I want to capture the inputs. Does this require a Listener? Can you capture as they type or do I need a button (Really, Really don't want a button)?
Also, I am unfamiliar with the layout of the java.
Oncreate is when the program boots up?
onCreateview is when the Fragment is booted up?
onattach is when the main activity is associated?
ondetach is when its associated from activity?
I don't fully understand yet where the best place is to add stuff, would it be after onattach?
Thanks for pointing me in the right directions guys.
Chris W.

Categories

Resources