In my application I need to disable display power off when device is charging. There is an option in Developer Menu to disable it, so I can to send Intent for user to enable it.
Also I've found info about PowerManager and WakeLocks, but it is for Alarms, I think. And I must to handle, is device charging.
What is the better, or is there another way to do this?
I've do this by that code:
final boolean isStayAwake = isStayAwakeEnabled(context);
if (!isStayAwake) {
intent = new Intent(ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
}
context.startActivity(intent);
There user must check 'stay awake' option
I've used my own ACTION_APPLICATION_DEVELOPMENT_SETTINGS constant because of problems with default one, which have not "com." prefix
Perhaps you want to try FLAG_KEEP_SCREEN_ON from the WindowManager.LayoutParams
Related
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:".
I am trying to capture the result of Intent.createChooser to know which app a user selected for sharing.
I know there have been a lot of posts related to this:
How to know which application the user chose when using an intent chooser?
https://stackoverflow.com/questions/6137592/how-to-know-the-action-choosed-in-a-intent-createchooser?rq=1
How to get the user selection from startActivityForResult(Intent.createChooser(fileIntent, "Open file using..."), APP_PICKED);?
Capturing and intercepting ACTION_SEND intents on Android
but these posts are somewhat old, and I am hoping that there might be some new developments.
I am trying to implement a share action without having it be present in the menu. The closest solution to what I want is provided by ClickClickClack who suggest implementing a custom app chooser, but that seems heavy handed. Plus, it seems like there might be some Android hooks to get the chosen app, like the ActivityChooserModel.OnChooseActivityListener.
I have the following code in my MainActivity, but the onShareTargetSelected method is never getting called.
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, shareMessage());
sendIntent.setType("text/plain");
Intent intent = Intent.createChooser(sendIntent, getResources().getText(R.string.share_prompt));
ShareActionProvider sap = new ShareActionProvider(this);
sap.setShareIntent(sendIntent);
sap.setOnShareTargetSelectedListener(new ShareActionProvider.OnShareTargetSelectedListener() {
#Override
public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
System.out.println("Success!!");
return false;
}
});
startActivityForResult(intent, 1);
As of API level 22 it is now actually possible. In Android 5.1 a method (createChooser (Intent target, CharSequence title, IntentSender sender)) was added that allows for receiving the results of the user's choice. When you provide an IntentSender to createChooser, the sender will be notified by the chooser dialog with the ComponentName chosen by the user. It will be supplied in the extra named EXTRA_CHOSEN_COMPONENT int the IntentSender that is notified.
I am trying to capture the result of Intent.createChooser to know which app a user selected for sharing.
That is not possible.
Other "choosing" solutions, like ShareActionProvider, may offer more. I have not examined the Intent handed to onShareTargetSelected() to see if it contains the ComponentName of the chosen target, though the docs suggest that it should.
And, if for some reason it does not, you are welcome to try to fork ShareActionProvider to add the hooks you want.
The reason why createChooser() cannot be handled this way is simply because the "choosing" is being done by a separate process from yours.
I have the following code in my MainActivity, but the onShareTargetSelected method is never getting called.
ShareActionProvider goes in the action bar. You cannot just create an instance, call a couple of setters, and expect something to happen.
I am launching the camera app in normal or secure mode depending on what gesture is performed using my app but once the user selects the app and taps Always then there is no option to change the defaults, even from the settings menu in Android.
camera_intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
secure_camera_intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
camera_intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
secure_camera_intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
this.startActivity(camera_intent);
//this.startActivity(secure_camera_intent);
Is there a workaround? I want to show the camera selection dialog once again so that the user can change his choice.
If you want to present the app chooser even if the user has a default activity selected for the task, use Intent.createChooser().
From the Android developer guide:
If you call Intent.createChooser(), passing it your Intent object, it
returns a version of your intent that will always display the chooser.
This has some advantages:
Even if the user has previously selected a default action for this intent, the chooser will still be displayed.
If no applications match, Android displays a system message.
You can specify a title for the chooser dialog.
You should also check the documentation for ACTION_CHOOSER for guidelines on where this is appropriate or not (Intent.createChooser() is just a convenience method for this).
startActivity(Intent.createChooser(senderIntent, "Title here"));
It will always display the chooser dialog.
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.
I'm planning on doing a application for Android 2.1 that changes song every minute (through what I hope exists in Android, "next") for the application using the audio device atm.
So if I have Spotify running in background already, playing music, can I through my program change to the next track?
Let me know if I was unclear about anything.
Thanks in advance!
I know this is a bit old question, but it took me some time searching something other then what is mentioned here.
There is a workaround - broadcasting media button action. There is one catch - receiver can recognize if the broadcast was from system or from another app, so they can ignore the non-system broadcasts.
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
synchronized (this) {
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT));
sendOrderedBroadcast(i, null);
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT));
sendOrderedBroadcast(i, null);
}
There's no universal audio transport API for music applications, so you'd need to see if the music applications you're targeting publicly expose service bindings or intents. If not, you won't be able to do this.
Just posted a relevant answer here
Using the AudioManager's dispatchMediaKeyEvent() method with a defined KeyEvent worked for me using the latest SDK.
The system music homescreen widget sends this intent for the built-in music player:
final ComponentName serviceName = new ComponentName(context,
MediaPlaybackService.class);
intent = new Intent(MediaPlaybackService.NEXT_ACTION);
intent.setComponent(serviceName);
pendingIntent = PendingIntent.getService(context,
0 /* no requestCode */, intent, 0 /* no flags */);
views.setOnClickPendingIntent(R.id.control_next, pendingIntent);
But it looks like this might take some hackery to implement outside packages in the music app itself because the MediaPlaybackService only accepts explicit Intents and isn't accessible from the outside. This thread seems to indicate it's possible with a bit of hackery, though.
But even then, as Roman said, not every music player will respect that Intent. You'll have to check with Spotify/Pandora/Last.fm themselves and see if they have any available intents to bind like that.
Looks that it's possible to use AudioManager to inject media keys.
Here is a snippet from another question
this.mAudioManager = (AudioManager) this.context.getSystemService(Context.AUDIO_SERVICE);
long eventtime = SystemClock.uptimeMillis();
KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT, 0);
mAudioManager.dispatchMediaKeyEvent(downEvent);
KeyEvent upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT, 0);
mAudioManager.dispatchMediaKeyEvent(upEvent);
The same way you can inject PlayPause button and some others.
I've tested it within a background service controlling Youtube and it worked for Android 6