How to use intent.setData() for changing system settings? - java

I discovered this code online that sends the user directly to the where they need to change the app's system write settings:
Intent writePermission = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
writePermission.setData(Uri.parse("package:" + MainActivity.this.getPackageName()));
MainActivity.this.startActivityForResult(writePermission, 4);
I want to do the same thing but for an accessibility service. I have this code here but it's lacking the second line of the above code that sends the user to the needed service:
Intent changeSettings = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivityForResult(changeSettings, 2);
I want to send the user directly to WindowChangeDetectingService rather than have them look it up in a list.

I discovered this code online that sends the user directly to the where they need to change the app's system write settings
That optional Uri is covered in the documentation for that Intent action.
I want to do the same thing but for an accessibility service.
The documentation for ACTION_ACCESSIBILITY_SETTINGS does not indicate that there is such an option.

Related

AdColony Aurora Android 3.0 SetCustomID

I'm attempting to integrate AdColony into an app. I'd like to set a custom ID for each user that gets passed back in the server to server callback I can setup in their dashboard. Right now the custom ID field returns null because it isn't set.
From what I can tell in their new java docs, they seem to have removed the setCustomID call from the AdColony class - or just overlooked it.
Their old docs for 2.3.6 have a built in method that makes it easy to do.
Apparently the name has changed to setUserID() and is now located on the AppOptions object. So you can do it like this:
AdColonyAppOptions options = new AdColonyAppOptions();
options.setUserID("MY USER ID");
AdColony.configure(this, options, "MY APP ID", "MY ZONE ID");

Sending image to Hangouts from local folder

I'm attempting to send an image to Hangouts from within an app I'm building.
I'm working in Xamarin for VS 2015 to do this so the code below is c# but it's not much different from the equivalent Java code so I think it's easy to follow.
What I've done is set up a button on my app which has code setting up an Intent to share an image to Hangouts. I've set the image up already in the Downloads folder on the device and hardcoded the name into the code.
Intent hangoutsShareIntent = new Intent(Intent.ActionSend);
hangoutsShareIntent.SetType("image/jpeg");
hangoutsShareIntent.SetPackage("com.google.android.talk");
string downloadsPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
string filePath = Path.Combine(downloadsPath, "shared.jpg");
hangoutsShareIntent.PutExtra(Intent.ExtraStream, filePath);
StartActivity(Intent.CreateChooser(hangoutsShareIntent, "Share with"));
When I run this, I get the option to select a chat in Hangouts that I want to send the content to. Upon selecting the chat, I get a blank message box and no image.
I've swapped the above code over to use text/plain and pass the filePath variable to the message. When I copy the file path into Chrome to check it, the image loads so I have to figure that the image is where I've said it is... right?
I get no errors (probably because the issue is in Hangouts rather than my app so I have nothing to debug there). Logcat shows nothing except an error I can't find much about on Google: ExternalAccountType﹕ Unsupported attribute readOnly
The only information I could find on that error implied some issue with permissions but I've made sure my app has runtime permissions checked for Read/Write using this code (which wraps the above):
if ((CheckSelfPermission(Permission.ReadExternalStorage) == (int)Permission.Granted) &&
(CheckSelfPermission(Permission.WriteExternalStorage) == (int)Permission.Granted))
NOTE: I'm running this on a HTC One M8 - no SD card but does have external storage on device. I've also added the above permissions to the manifest for earlier Android versions.
The documentation for this (here) isn't overly helpful either so any advice AT ALL here is welcome :)
Thanks!
If you use the file provider instead of sending just the URI on its own. This should get around the permission issues you are seeing.
There is a guide available here which might be useful.
Intent shareIntent = new Intent(Intent.ActionSend);
shareIntent.SetType("image/gif");
Java.IO.File file = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory + "/myimage.gif");
Android.Net.Uri fileUri = Android.Support.V4.Content.FileProvider.GetUriForFile(this, "com.myfileprovider", file);
shareIntent.SetPackage("com.google.android.talk");
shareIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
shareIntent.PutExtra(Intent.ExtraStream, fileUri);
StartActivity(Intent.CreateChooser(shareIntent, "Share with"));

Android direct shared

I am trying to share a link from my app with direct share. The share dialog must be like the image below with the most used contacts from messaging apps, like WhatsApp contacts.
This is the Intent structure which I am using for share the link:
Intent shareIntent = ShareCompat.IntentBuilder
.from(getActivity())
.setType("text/plain")
.setText(sTitle+ "\n" + urlPost)
.getIntent();
if (shareIntent.resolveActivity(
getActivity().getPackageManager()) != null)
startActivity(shareIntent);
And this is what my app shows:
Any idea how to achieve that?
You should use .createChooserIntent() instead of .getIntent()
Like this code below, you can use Intent.createChooser
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
Uri screenshotUri = Uri.parse("file://" + filePath);
sharingIntent.setType("image/png");
sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
startActivity(Intent.createChooser(sharingIntent, "Share image using"));
You should use .createChooserIntent() instead of .getIntent()
Docs: This uses the ACTION_CHOOSER intent, which shows
an activity chooser, allowing the user to pick what they want to before proceeding. This can be used as an alternative to the standard activity picker that is displayed by the system when you try to start an activity with multiple possible matches, with these differences in behavior:
You can specify the title that will appear in the activity chooser.
The user does not have the option to make one of the matching activities a preferred activity, and all possible activities will
always be shown even if one of them is currently marked as the
preferred activity.
This action should be used when the user will naturally expect to
select an activity in order to proceed. An example if when not to use
it is when the user clicks on a "mailto:" link. They would naturally
expect to go directly to their mail app, so startActivity() should be
called directly: it will either launch the current preferred app, or
put up a dialog allowing the user to pick an app to use and optionally
marking that as preferred.
In contrast, if the user is selecting a menu item to send a picture
they are viewing to someone else, there are many different things they
may want to do at this point: send it through e-mail, upload it to a
web service, etc. In this case the CHOOSER action should be used, to
always present to the user a list of the things they can do, with a
nice title given by the caller such as "Send this photo with:".

Initiliazing ParseLoginUI?

Where does one actually place the code to launch the ParseLoginUI activity?
ParseLoginBuilder builder = new ParseLoginBuilder(MainActivity.this);
startActivityForResult(builder.build(), 0);
Is it in the ParseLoginDispatchActivity? This was not made very clear at all within any of the official documentation:
https://github.com/ParsePlatform/ParseUI-Android
https://www.parse.com/docs/android/guide#user-interface
I'm importing ParseLoginUI into my existing app. What do I once I've installed everything, updated my manifests, my build.gradle and now want to actually launch the Login activity once my app launches?
Do I put something in my manifest to indicate that the ParseLoginActivity should launch first? That doesn't seem to work as an Activity from my main application is required to launch as the initial intent. I'm a little lost here... Any thoughts?
Well I did find one solution, albeit a trivial one:
Intent loginIntent = new Intent(MainActivity.this, ParseLoginActivity.class); startActivity(loginIntent);
I launched the above Intent with an options menu item, but you could do it with a button or whatever else suits your needs.
If you're importing ParseLoginUI into an existing app, it appears you can just launch ParseLoginActivity with a simple Intent. I wish they mentioned this on their integration tutorial. Seems like the most straightforward way to get it running.
This solution definitely launches the Activity you want, but it doesn't check for whether the user is logged in or not and hence doesn't redirect you to the appropriate pages in your log-in flow (which I believe has more to do with your Manifest). It does, however, allow you to successfully register a user and log in with Parse, which is a great start.
A better solution would be to add the following to the onCreate method in the Activity that launches when your app launches. So if when your app launches you land on FirstActivity, the following will check to see if you are logged in. If you are not, you will be sent the login screen, and if you are logged in you will be sent to the second Activity, which is presumably where your users will want to be when they open your app.
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser != null) {
Intent launchMainActivity = new Intent(this, SecondActivity.class);
startActivity(launchMainActivity );
} else {
ParseLoginBuilder builder = new ParseLoginBuilder(FirstActivity.this);
startActivityForResult(builder.build(), 0);
}

Use system PIN dialog in Android application

Background
I am trying to write an application which works like described below.
When user start application it check if user have registered PIN on his device.
If user have registered PIN, application must show button "Continue with PIN".
When user press on button "Continue with PIN" system standard PIN dialog must appears.
User enter his PIN and press "Continue" button.
After System must check if entered PIN is correct or no and continue working.
Searches
I have made some searches and found some articles on stackoverflow and other internet sources which say "There is no way to develop a new custom unlock mechanism on a non-rooted phone." or "I would be surprised if you could, because then you would be probably able to steal the pin code, and I don't think anyone would want that.".
Also I have watched some video tutorials like Tutorial: Android Internals - Building a Custom ROM, Pt. 1 of 2 and Tutorial: Android Internals - Building a Custom ROM, Pt. 2 of 2.
EDITED
I have made some searches today and found a very interesting thing, I think I am on a right way to the solution, and I want to share my ideas with you. So looking in android sources I found an interesting files ChooseLockPassword.java (packages\apps\Settings\src\com\android\settings) and LockPatternUtils.java (*frameworks\base\core\java\com\android\internal\widget*) now I am interest in:
Question
How can I call LockPatternUtils class function from my code ? Or Why I cant see that function in Eclipse ?
Decision
So I think that the only way to get access to the Android system PIN dialog is to root the phone make some changes in the system files and use system PIN dialod
Question
Can somebody provide me useful links about getting access to the system PIN dialog in the rooted phone.
Am I on a right way and can I solve my problem in this way?
If anybody encountered such problem please help me to solve.
Any Solutions?
Okay, I have solved this problem and now I want to share my solution with you.
At first as I told I have android sources so I have made some changes in android sources to get access to the PIN and Pattern dialogs. And here they are:
in ~\AndroidSources\pakages\apps\Settings\AndroidManifest.xml I have changed following lines of code
<activity android:name="ConfirmLockPattern"
android:exported="true"> // This line was added by me.
</activity>
<activity android:name="ConfirmLockPassword"
android:exported="true" // This line was added by me.
android:them="#android:style/Them.NoTitleBar">
</activity>
<activity android:name="ChooseLockPattern"
android:exported="true" // This line was added by me.
android:label="#string/lockpattern_change_lock_pattern_label">
</activity>
This modifications allow me to call "ConfirmLockPattern", "ConfirmLockPassword" and "ChooseLockPattern" activities from my own application. After I compile android Source codes and launch system.img on my emulator.
In my application I have write following functions in order to call "ConfirmLockPattern" or "ChooseLockPattern" activities:
/**
* Show PIN/Password confirmation dialog.
*/
void ShowConfirmLockPINActivity() {
CustomLog.i(TAG, "Show Confirm Lock PIN Activity");
Intent intent = new Intent(Intent.ACTION_RUN);
intent.setComponent(new ComponentName("com.android.settings",
"com.android.settings.ConfirmLockPassword"));
startActivityForResult(intent, mRequestCode);
} /* ShowConfirmLockPINActivity() */
/**
* Show set PIN/Password dialog.
*/
void ShowSetLockPINActivity() {
CustomLog.i(TAG, "Show Set Lock PIN Activity");
Intent intent = new Intent(Intent.ACTION_RUN);
intent.setComponent(new ComponentName("com.android.settings",
"com.android.settings.ChooseLockPassword"));
startActivityForResult(intent, mRequestCode);
} /* ShowSetLockPINActivity() */
/**
* Show Pattern Confirmation dialog.
*/
void ShowSetLockPatternActivity() {
CustomLog.i(TAG, "Show Set Lock Pattern Activity");
Intent intent = new Intent(Intent.ACTION_RUN);
intent.setComponent(new ComponentName("com.android.settings",
"com.android.settings.ConfirmLockPattern"));
startActivityForResult(intent, mRequestCode);
} /* ShowSetLockPatternActivity() */
Here are some considerations regarding your question.
Diving deep into Android's code is not very good idea in this particular case, since verifying PIN code is an important security point and its mechanism must be hidden and well protected to avoid any malicious intentions.
Thus, the actions you want to perform (ask for PIN and then check it against real PIN) are prohibited and would look like an intrusion. So, you shouldn't try to get an access to the storage of user passwords.
It would be more correct to try launching standard PIN screen via some Intent and ask it to make all job for you. However, a brief investigation didn't give me any results in this direction; perhaps, you'll find something.
Modifying the ROM is obviously dead-end - no one will flash the phone to install one app. Requiring rooted phone is a bit better, there are apps that cannot run on non-rooted phone, but still it forwards us back to the point #2 (intrusion).
Users may disable PIN check and there are devices with no SIM.
So, according to the all mentioned I'd suggest you think of different verification method for your app.
Since API level 21 there is KeyguardManager.createConfirmDeviceCredentialIntent that can be used to authenticate current user with the device lock pin.
See the usage example.

Categories