How to disable SMS notification programmatically? - java

This not work:
try {
Context mmsContext = context.createPackageContext("com.android.mms", Context.CONTEXT_IGNORE_SECURITY);
mmsContext.grantUriPermission(context.getPackageName(),
Uri.parse("file:///data/data/com.android.mms/shared_prefs/com.android.mms_preferences.xml"),
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mmsContext);
Editor editor = settings.edit();
editor.putBoolean("pref_key_enable_notifications", false);
editor.commit();
} catch (NameNotFoundException e1) {
e1.printStackTrace();
}
Error: "Attempt to read preferences file /data/data/com.android.mms/shared_prefs/com.android.mms_preferences.xml without permission"
Help, please!

You cannot disable SMS notifications programmatically. Please allow the user to decide whether or not SMS notifications should be enabled and allow them to control it through the appropriate settings screen.

By "you cannot", do you mean you should not, or there is no clean way of doing it/there's no API for that? Or do you really mean there is no way?
In most cases, I fully agree with you that the user should be able to control it through the appropriate settings screen. However, unfortunately, there are cases where there is no settings screen to toggle message notifications. An example I know of is the Samsung Behold II (which replaces the default messaging app, and removes the option to set/unset message notifications). I'm trying to develop a way around this, as there have been several requests by Behold II owners who've installed alternative MMS/SMS apps, and do not want the double notification.
I've tried to access the preference activity directly using the following code, but it forced closed
final Intent messagesettings = new Intent();
messagesettings.setClassName("com.android.mms", "com.android.mms.ui.MessagingPreferenceActivity");
...
public void onClick(View view){
startActivity(messagesettings);
}
Any ideas?

Related

NFC is on, but adapter is not enabled

I am working on android project, where NFC is used as a communication. I am facing a weird problem, when mobile device has a NFC, it is enabled, but it is not working on some devices (adapter is not enabled when debugging). I am writing logs and it prints, NFC on, adapter disabled.
For example: HTC One m9(os 7.0). Also happens with OnePlus One(os 9)! But again, it works on other devices.
Did you experience the same issue?
Here is some code:
object NfcUtil {
fun getNfcAdapter(c: Context): NfcAdapter? {
val manager = c.getSystemService(Context.NFC_SERVICE) as NfcManager
return manager.defaultAdapter
}
fun doesSupportHce(c: Context): Boolean {
return c.packageManager.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
}
}
val adapter = NfcUtil.getNfcAdapter(this)
if (adapter != null && NfcUtil.doesSupportHce(this)) {
if (adapter.isEnabled) {
tvNfcOff.extHide()
} else {
tvNfcOff.extShow()
}
}
I think that if NFC is supported and enabled but the adapter is disabled (https://developer.android.com/reference/android/nfc/NfcAdapter#isEnabled()) I'll follow the guidelines and redirects the user to the settings screen with the intent mentioned in the documentation.
If the user come back few times you could monitor it and show a different message instead of redirecting to settings, something like: NFC is not working properly on your device. I'd check if you have lots of users using those devices, if yes, I will try to research more on the Operating System and Device having this issue.
And later on I will just try to debug it with that Device and that specific Operating System that is having this kind of issue. I'll try to see if other apps using NFC has same issues or they work fine, and by work fine I mean that the communication happens not that other apps dont show any warning/error popup message.
And if I found out its an issue in a specific OS Version, also with other apps, I'll just try to inform the users and get an update on which version the issue have been fixed. Otherwise if other apps can make a successful NFC communication in that device/OS that is not working for me, I'll just dig deeper.
For now I can say there is nothing wrong in your implementation and looks good.
It might be an issue with the current OS or if you have any Custom ROM that might not fully support or have a functional NFC driver.
Two additional bits of info that might be useful
1) Use a Broadcaster receiver to get notified when the NFC state changes, because using the quick settings pull down does not pause your app, therefore retesting nfc status in onResume does not work (a user changing via the full settings app will pause you App, though)
Example of how to do it in Java
#Override
protected void onCreate(Bundle savedInstanceState) {
// All normal onCreate Stuff
// Listen to NFC setting changes
this.registerReceiver(mReceiver, filter);
}
// Listen for NFC being turned on while in the App
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)) {
final int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
NfcAdapter.STATE_OFF);
switch (state) {
case NfcAdapter.STATE_OFF:
// Tell the user to turn NFC on if App requires it
break;
case NfcAdapter.STATE_TURNING_OFF:
break;
case NfcAdapter.STATE_ON:
// Do something with this to enable NFC listening
break;
case NfcAdapter.STATE_TURNING_ON:
break;
}
}
}
};
2) Don't assume that the device has a NFC settings page, if your app works with and without NFC, if the adapter is null don't assume you can start an Intent to the NFC settings page as suggested by #denis_lor as this will cause a crash if the OS does not have a NFC adapter to turn on.

Display Twitter user profile without logging in?

I would like to display a twitter user profile without having the app prompt the phone user for creating an account or login information.
public void openTwitter(View view){
try
{
// Check if the Twitter app is installed on the phone.
getPackageManager().getPackageInfo("com.twitter.android", 0);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setClassName("com.twitter.android", "com.twitter.android.ProfileActivity");
intent.putExtra("user_id", 01234567L);
startActivity(intent);
}
catch (PackageManager.NameNotFoundException e)
{
// If Twitter app is not installed, start browser.
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/xxx")));
}
}
The code opens the twitter app and prompts the phone user for account creation before viewing profile xxx. I would like to simply view profile xxx without creating an account or logging in.
Welcome to StackOverflow. Please check out how to ask a good question first. Your question doesn't describe a specific problem and therefore can't be "solved". It also isn't specific enough for anyone to point you in the direction of methods to use to achieve your goal.
That being said, if you just want to display anyone's profile, implement the Twitter API in your app and make the right REST calls and you should get the information you want to display.
If you want the user's profile specifically, there's literally no way around the user logging into their account with the API, unless they previously define their username in your app.
If you just want to display the profile and don't care about designing the information yourself, you could use a WebView to open the link to the profile you want to open, or use UIApplication.shared.open to open a link outside your own app.

java.lang.SecurityExeception :Clearing DeviceOwner data is forbidden

I am trying to clear a data from within the app and my app is device owner, hence I am getting and error
java.lang.SecurityExeception :Clearing DeviceOwner data is forbidden.
Code I am using is
public void onClearData(View view) {
try {
boolean isCleared = ((ActivityManager) getSystemService(ACTIVITY_SERVICE)).clearApplicationUserData();
if (!isCleared) {
Toast.makeText(this, "Not able to clear the data", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Now, my question is that how it will be possible to clear a data of device owner app from within the app? Would appreciate a help.
The way you're doing it is how it's done, according to the docs.
But since you're getting that security exception, your app is probably set as a device owner app, and you're not allowed to deactivate it, remove its data nor uninstall it while it is on this state.
If that's really the case I'd suggest you to unset it as a Device Owner App. Try to use dpm remove-active-admin for that.
Take a look at those questions for more info:
How to make my app a device owner?
How to remove set-device-owner in Android DPM?
Disable a device owner app from android terminal

Is there a way to find out how long an app is installed?

I would like to find out how long an app is already installed on a device.
The reason :
I like to announce a new update for the app for users who have installed the app longtime ago and want to prevent to announce this for users, which have just installed the app. I hate myself advertising in the apps :-) so I want to be discreet and show the announcement for only users which have installed the app longtime ago. (Sorry for my bad english)
what i do not want to use is this the following, because this allow me to detect this only from a newer version, where I implemented it:
- using google analytics.
- a counter which counts the appstarts in a property
I am looking for a solution that I implement now in 2014 and detects that an app is installed since 2013.
any hints ?
The easiest way to do this moving forward would be with a pair of SharedPreferences:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(new Context());
boolean firstRun = prefs.getBoolean("IS_FIRST_RUN", true);
long now = System.currentTimeMillis();
if (firstRun)
{
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("IS_FIRST_RUN", false);
editor.putLong("FIRST_RUN_MILLIS", now);
editor.apply();
}
else
{
long dateFirstRun = prefs.getLong("FIRST_RUN_MILLIS", 0L);
if (dateFirstRun == 0L)
{
// no value saved. decide how you want to handle
}
else if (now - dateFirstRun < SOME_AGE)
{
// offer extra functionality
}
}
If you want to check past installs I think you will have to play with the PackageManager
Edit: As Richard suggests in the comments above:
try
{
long firstInstall = context.getPackageManager().getPackageInfo("package.name", 0).firstInstallTime;
}
catch (PackageManager.NameNotFoundException e)
{
e.printStackTrace();
}
In my experience, if the app is on Google Play, I would use some service like UrbanAirship, Parse, or raw GCM implementation with personal server to register devices and be able to send push messages to every handset.
I wouldn't mind about the already installed apps 'cause the Play Store app on the device will announce the user about the update when available.
Now, if the app is not on Google Play, but still consumes an api, you can take advantage of it and send a one-time promotional message to download the new version with the new features:
//TODO Receive message here
//check preferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if(!prefs.getBoolean("alreadyAdvertised", false)){
prefs.edit().putBoolean("alreadyAdvertised", true).commit();
//TODO display message here
}
Hope it helps.

Staying 'logged in' even when app destroyed

Hi I have an App which has a strict requirement of appearing "logged in" even following the app being destroyed. If the App was destroyed then later re-loaded (if previously logged in) login screen should be bypassed > directly to the page the user was previously viewing. (I already handle all session related variables)
I've tried using Shared Preferences but if I destroy the App manually it would go back to the login screen, I can't have this happen.
I tried storing preferences manually in the DB (which is probably what Shared Preferences does anyway?) but it still loads the Login Activity of course because this is my first loaded activity. So this problem is more a case of keeping a preference on which Activity the user is on at all time then loading directly to this onResume().
My question: Has anyone dealt with this sort of scenario before? How should I approach pre-loading the Activity. I was thinking that when I load my preferences within the Login screen I check the previous Activity preference and simply load into that (assuming user is logged in).
Is there a better way to approach this? Is there a more native way of loading dynamically to appropriate Activity start?
Any help is really appreciated
Edit: Ok just after posting this I realised all I really had to do was add a check in OnResume whether the appropriate session variable was set. then load into the Activity, actually just as Akbari says below. I've rolled my Preferences class back to using the standard Android SharePreferences and its working perfectly now. happy about that :)
Simply doing something like this:
// load preferences
preferences.readPreferences();
// if preferences exist load straight to RecordActivity
if (application.currentSessionId!=null) {
Intent i = new Intent(getApplicationContext(), RecordActivity.class);
startActivity(i);
}
you can save login status in preferences and check it in onCreate() method of your Login activity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);SharedPreferences prefs;
prefs = getSharedPreferences("your_pref", MODE_PRIVATE);
boolean login_status = prefs.getBoolean("login_status", false);
if (login_status) {
Log.v(LOG_TAG, "UserInfo>>User already logged in");
Intent intent = new Intent(this, HomeActivity.class);
startActivity(intent);
this.finish();
}
}
Here, it will check login status and redirect user to next activity if already logged in

Categories