Working with notifications - Xposed General

Hi, I have code below to create a notification, but after click on any button, NotificationActivity does not start, any ideas?
Java:
Context parent =AndroidAppHelper.currentApplication();
// Enable
Intent allow = new Intent(parent, NotificationActivity.class);
allow.putExtra("AppName", Appname);
allow.putExtra("Option", "ALLOW");
allow.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingAllow = PendingIntent.getBroadcast(parent, 0, allow, 0);
NotificationCompat.Action allowAct = new NotificationCompat.Action(0, "Allow", pendingAllow);
// Disable
Intent mute = new Intent(parent, NotificationActivity.class);
mute.putExtra("AppName", Appname);
mute.putExtra("Option", "MUTE");
mute.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingMute = PendingIntent.getBroadcast(parent, 0, mute, 0);
NotificationCompat.Action muteAct = new NotificationCompat.Action(0, "Mute", pendingMute);
// Disable always
Intent muteAlways = new Intent(parent, NotificationActivity.class);
muteAlways.putExtra("AppName", Appname);
muteAlways.putExtra("Option", "MUTE ALWAYS");
muteAlways.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingMuteAlways = PendingIntent.getBroadcast(parent, 0, muteAlways, 0);
NotificationCompat.Action muteAlwaysAct = new NotificationCompat.Action(0, "Mute always", pendingMuteAlways);
// setup
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(parent)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Notification")
.setContentText(Appname)
.setAutoCancel(true)
.addAction(allowAct)
.addAction(muteAct)
.addAction(muteAlwaysAct);
NotificationManager nManager = (NotificationManager) parent.getSystemService(Context.NOTIFICATION_SERVICE);
nManager.notify(36, mBuilder.build());

I'm assuming NotificationActivity is a class in your app, in which case it wouldn't exist in the hooked app.
You'll want to use an explicit intent if that's possible (if memory serves right, it is), or look into an alternative way.

Related

How do you get the number of items in a spinner control

I am trying to use m_BTArrayAdapter.getCount()
However this function returns 0 regardless of what is in the spinner popup.
I found some doco on this function: http://developer.android.com/reference/android/widget/ArrayAdapter.html#getCount%28%29
"public int getCount ()"
That is - no description. So what does that mean? In android Studio this function is redundant?
There are no other functions that I can see that tell you how many items there are in an ArrayAdapter or in the spinner control itself.
Surely I don't have to resort to a counter in my BT listener function to keep count of how many items are added to the adapter????
Code:
void setupBTListener()
{
m_BTArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item);
final Spinner spinnerBluetooth = (Spinner)findViewById(id.spinner_bluetooth);
spinnerBluetooth.setAdapter(m_BTArrayAdapter);
Can anyone explain to me why m_BTArrayAdapter.getCount() returns non zero inside my listener function but zero in the code below?
Code:
m_BTArrayAdapter.clear();
if (m_BTAdapter.isDiscovering())
m_BTAdapter.cancelDiscovery();
m_BTAdapter.startDiscovery();
long longStart = System.currentTimeMillis(),
longTimer;
boolean bDone = false;
while (m_BTAdapter.isDiscovering() && !bDone)
{
longTimer = System.currentTimeMillis();
//bDone = (longTimer - longStart) < 5000;
}
bEnable = m_BTArrayAdapter.getCount() > 0;
spinnerBluetooth.setEnabled(bEnable);
buttonConnect.setEnabled(bEnable);
buttonSearch.setEnabled(true);

Location Returns Null

Good day!
Hello! Every time I try to get my location using Google Maps in my Android application, it returns "null" or doesn't get my location.
If I test my code with Mock Locations, which grants the statement "if ( myLocation != null ){}" the code works.
But the statement "if ( myLocation == null ){}" doesn't do anything.
Help is greatly appreciated.
Code:
@Override
public void onMapReady(GoogleMap googleMap) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
}, 10);
}
return;
}
gMap = googleMap;
if(!gMap.isMyLocationEnabled())
gMap.setMyLocationEnabled(true);
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location myLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (myLocation == null) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
String provider = lm.getBestProvider(criteria, true);
myLocation = lm.getLastKnownLocation(provider);
}
if(myLocation != null) {
LatLng userLocation = new LatLng(myLocation.getLatitude(), myLocation.getLongitude());
gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 14), 1500, null);
//LONG CODE THAT CONTAINS GOOGLE MAP MARKERS. POLYLINES, RADIUS, Location.distanceBetween() statements
}
Hello,
The GPS on your device must be enabled. You could redirect your users to offer them to enable GPS and then when they will be back on your screen, you should be able to get a location.
Sylvain

Trouble setting off notifications with broadcast receiver

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());
}
}

Module stops working as soon as I load a native library (Please help)

Hi,
First, a disclaimer.
I am a Java and xposed noob. My background is in embedded C development so I can get by with some simple Java code and thanks to the great tutorials online I have been able to put together an xposed module but I'm struggling with a problem that is beyond my abilities now and am reaching out to the community for help.
Next, the background.
I have an Android head unit in my car. There is an app that provides me with CarPlay functionality but none of the controls on the steering wheel work with the app. When I analysed the code I found that they handle all of their button inputs using proprietary methods that do not inject an event into any input streams. I wrote an xposed module to hook the button press methods and then inject a proper input into one of the event streams.
Initially I tried to use the command line 'input' command to do this but since it is a Java app and takes about 1s to load it was too slow. My only other option was to create a virtual device on an input stream that I could then use to inject keypresses through the hooked method. To create a virtual device I needed to write C code that my xposed module would be able to access through the JNI. Long story short, after some pain I was able to get the native library integrated into the project and compiling using the NDK.
Finally, the problem.
When I was using the module without the native library it worked but just with a large delay because of the time it takes to load the 'input' java app. I was able to see logs from the module in the logcat as I hooked the method and as I went through the various actions within the hook.
As soon as I introduce the native library though the entire xposed module just stops running completely. I do not get any logs from the module even though I have installed, activated and rebooted. It shows up in the xposed installer but it just does nothing. The funny thing is that this happens even if I make no reference whatsoever to any native functions within the library. All I need to do to kill the module is to build it with the System.loadlibrary line in the Main.java uncommented. As soon as I comment that piece of code out the module starts to hook the function and output logs again. Below is the code from the Main.Java that I am referring to. I am happy to make any manifest, C and gradle files available too. Looking for any ideas as to why the module dies completely as soon as I include this...
Code:
package projects.labs.spike.zlink_xposed_swc;
import de.robv.android.xposed.XposedBridge;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import de.robv.android.xposed.XposedHelpers;
import android.app.AndroidAppHelper;
import android.content.Intent;
import android.os.Bundle;
import android.content.Context;
/* shellExec and rootExec methods */
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import android.view.KeyEvent;
import android.media.AudioManager;
public class Main implements IXposedHookLoadPackage {
public static final String TAG = "ZLINK_XPOSED ";
public static void log(String message) {
XposedBridge.log("[" + TAG + "] " + message);
}
//public native int CreateVirtualDevice();
//public native int SendPrev();
@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
log("handleLoadPackage: Loaded app: " + lpparam.packageName);
if (lpparam.packageName.equals("com.syu.ms")) {
findAndHookMethod("module.main.HandlerMain", lpparam.classLoader, "mcuKeyRollLeft", new XC_MethodHook() {
@Override
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
// previous
log("PREVKEYHIT");
//rootExec("input keyevent 88");
log("EVENTSENT");
//Below was trying to use media keys which zlink never responded to...
/* Context context = (Context) AndroidAppHelper.currentApplication();
AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS);
mAudioManager.dispatchMediaKeyEvent(event);
KeyEvent event2 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PREVIOUS);
mAudioManager.dispatchMediaKeyEvent(event2);*/
//Below is the failed broadcast intent method...
/*Context mcontext = (Context) AndroidAppHelper.currentApplication();
Intent i = new Intent("com.android.music.musicservicecommand");
i.putExtra("command", "pause");
mcontext.sendBroadcast(i);*/
}
});
}
}
public static String rootExec(String... strings) {
String res = "";
DataOutputStream outputStream = null;
InputStream response = null;
try {
Process su = Runtime.getRuntime().exec("su");
outputStream = new DataOutputStream(su.getOutputStream());
response = su.getInputStream();
for (String s : strings) {
s = s.trim();
outputStream.writeBytes(s + "\n");
outputStream.flush();
}
outputStream.writeBytes("exit\n");
outputStream.flush();
try {
su.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
res = readFully(response);
} catch (IOException e) {
e.printStackTrace();
} finally {
Closer.closeSilently(outputStream, response);
}
return res;
}
public static String readFully(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = is.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos.toString("UTF-8");
}
[COLOR="Red"] static {
System.loadLibrary("native-lib");
}[/COLOR]
}
The issue with native library is quite strange and I cannot help with it as my experience with native libs is zero.
But maybe try a different method of injecting media key events.
Create a method:
Code:
void injectKey(int keyCode) {
try {
final long eventTime = SystemClock.uptimeMillis();
final InputManager inputManager = (InputManager)
mContext.getSystemService(Context.INPUT_SERVICE);
int flags = KeyEvent.FLAG_FROM_SYSTEM;
XposedHelpers.callMethod(inputManager, "injectInputEvent",
new KeyEvent(eventTime - 50, eventTime - 50, KeyEvent.ACTION_DOWN,
keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags,
InputDevice.SOURCE_KEYBOARD), 0);
XposedHelpers.callMethod(inputManager, "injectInputEvent",
new KeyEvent(eventTime - 50, eventTime - 25, KeyEvent.ACTION_UP,
keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags,
InputDevice.SOURCE_KEYBOARD), 0);
} catch (Throwable t) {
// something went wrong
XposedBridge.log(t.getMessage());
}
}
Then just do: injectKey(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
And maybe try playing with different KeyEvent flags and attrs.
Thanks so much for this suggestion! Any idea if this injects at a java level or if it depends on there being a keyboard input device available on one of the /dev/input/eventX streams? The android device that I am using has no keyboard available on any of those input streams. Will give it a try nonetheless
C3C076 said:
The issue with native library is quite strange and I cannot help with it as my experience with native libs is zero.
But maybe try a different method of injecting media key events.
Create a method:
Code:
void injectKey(int keyCode) {
try {
final long eventTime = SystemClock.uptimeMillis();
final InputManager inputManager = (InputManager)
mContext.getSystemService(Context.INPUT_SERVICE);
int flags = KeyEvent.FLAG_FROM_SYSTEM;
XposedHelpers.callMethod(inputManager, "injectInputEvent",
new KeyEvent(eventTime - 50, eventTime - 50, KeyEvent.ACTION_DOWN,
keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags,
InputDevice.SOURCE_KEYBOARD), 0);
XposedHelpers.callMethod(inputManager, "injectInputEvent",
new KeyEvent(eventTime - 50, eventTime - 25, KeyEvent.ACTION_UP,
keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags,
InputDevice.SOURCE_KEYBOARD), 0);
} catch (Throwable t) {
// something went wrong
XposedBridge.log(t.getMessage());
}
}
Then just do: injectKey(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
And maybe try playing with different KeyEvent flags and attrs.
Click to expand...
Click to collapse
looxonline said:
Thanks so much for this suggestion! Any idea if this injects at a java level or if it depends on there being a keyboard input device available on one of the /dev/input/eventX streams? The android device that I am using has no keyboard available on any of those input streams. Will give it a try nonetheless
Click to expand...
Click to collapse
Simply use whatever InputDevice that you think should work in your case.
The method basically calls this:
https://android.googlesource.com/pl.../android/hardware/input/InputManager.java#869
which is then propagated to Input Manager Service here:
https://android.googlesource.com/pl...oid/server/input/InputManagerService.java#598
which then calls nativeInjectInputEvent

Catch a emty value or null value?

In my program i show with chart from mpandroidchart values from json file taken from a sql table.
The problem is next.
If i get only values then the chart shows fine, but if i get a empty value , nothing is showed.
To catch that i want to make the empty fields 0.
The part that read the values is this.:
Code:
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String waarde = jsonObject.getString(waardekeuze);
String date = jsonObject.getString(datekeuze);
// if(waarde != null){ Entry values1 = new Entry(0, i);}
// else { Entry values1 = new Entry(Float.parseFloat(waarde), i);}
Entry values1 = new Entry(Float.parseFloat(waarde), i);
// if(waarde != null && !waarde.isEmpty()){waarde = 0}else{ Entry values1 = new Entry(Float.parseFloat(waarde), i);}
yas.add(date);
xas.add(values1);
The problem is , if the field waarde is nothing or 0 then i want that the value is always 0, so the chart has a number to plot.
You see that i tryed some things but nothing works.
How can i solve that?
pascalbianca said:
In my program i show with chart from mpandroidchart values from json file taken from a sql table.
The problem is next.
If i get only values then the chart shows fine, but if i get a empty value , nothing is showed.
To catch that i want to make the empty fields 0.
The part that read the values is this.:
Code:
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String waarde = jsonObject.getString(waardekeuze);
String date = jsonObject.getString(datekeuze);
// if(waarde != null){ Entry values1 = new Entry(0, i);}
// else { Entry values1 = new Entry(Float.parseFloat(waarde), i);}
Entry values1 = new Entry(Float.parseFloat(waarde), i);
// if(waarde != null && !waarde.isEmpty()){waarde = 0}else{ Entry values1 = new Entry(Float.parseFloat(waarde), i);}
yas.add(date);
xas.add(values1);
The problem is , if the field waarde is nothing or 0 then i want that the value is always 0, so the chart has a number to plot.
You see that i tryed some things but nothing works.
How can i solve that?
Click to expand...
Click to collapse
Solved by my self.

Categories

Resources