When you long press on something in Android, a context menu comes up. I want to add something to this context menu for all TextViews in the system.
For example, the system does this with Copy and Paste. I would want to add my own, and have it appear in every application.
Currently Android does not support this, you cannot override or hook functionality globally at the system level without the particular activity implementing an intent or activity that you expose. Even in the case of publishing an intent it wouldn't matter unless the application running is a consumer... and all the base system applications and obviously all applications prior to yours would not be without updating the app to consume.
Basically as it stands, this is not possible.
What exactly are you trying to accomplish with this global context menu, some sort of global "Search For" or "Send To" functionality that runs through your application?
Add intent-filter in your file android-manifest.xml:
<activity
android:name=".ProcessTextActivity"
android:label="#string/process_text_action_name">
<intent-filter>
<action android:name="android.intent.action.PROCESS_TEXT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
Get highlighted by user text in activity your app in method onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.process_text_main);
CharSequence text = getIntent()
.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT);
// process the text
}
More information in the article on medium.
Thanks for user: YungBlade
Him answer on ru.stackoverflow.com
This might be a little bit hacky, but you can trap the menu key at the application/activity level, check to see if your current active view is a text entry view, and then build and display your own custom popup menu.
It is possible, it's just a little tricky.
If you create/inflate a TextView, call setFocusable(false) on it, and then set it as the active view your Activity will still receive key events.
You will have to forward all those events (trackball, touch, key) to your View tree by hand. (Inside your "onKeyDown" function you'd have to call the appropriate "onKeyDown" method for the top level View) You effectively have to trap the notion of 'focus' and dole it out to the correct view yourself.
While a little ugly, it may give you the desired results.
This would, however, only work in your own application. Previous answers are correct about it being impossible across the entire phone.
Push the Share button (tree of three dots) within selection menu. Then you should select your own app. Does't work for input field content, unfortunately.
Hmm; I don't know if you can extend built in types like in example. Ruby (my Java knowledge is not so deep enough).
However you can derive your own MyTextView from TextView. Then substitute all your TextView in layouts like this:
<TextView android:id="#+id/TextView01" />
to
<com.mydomain.mypackage.MyTextView android:id="#+id/TextView01" />
to automatically change type of all these fields.
Then you need to override all constructors
(especially TextView(Context context, AttributeSet attrs) ).
After that all layout inflaters (automatic or manual) will create this type with no fuss.
Then you can create/register context menu callbacks as you wish.
Related
I have a problem when I rotate my device, my activity is re-executed and the values change.For example, suppose that you have an activity with a button, when this button is clicked, it will show the increased value in a text view (a counter). And when you put your device in landscape mode, the activity will run again, and you will see (again) the value increased. My question is, is there a way to not run the activity again when you rotate the device ?
Please read this. You will see that there are two solutions for handling configuration changes:
You can declare that you are handling the change on your own by updating activity in the manifest. This way your activity will not be restarted and onConfigurationChanged() will be called:
<activity ...
android:configChanges="orientation|screenSize"
...>
You can pass your data objects to the new activity via onSaveInstanceState() function. Passing large objects can slow down the app. It is better you separate data from the view for example by using ViewModels, which are retained in these kind of changes.
First way may seem easy, but it is not recommended as you can see in the link provided at the beginning:
Caution: Handling the configuration change yourself can make it much
more difficult to use alternative resources, because the system does
not automatically apply them for you. This technique should be
considered a last resort when you must avoid restarts due to a
configuration change and is not recommended for most applications.
Add android:configChanges in your activity
<activity name= ".YourActivity" android:configChanges="orientation|screenSize"/>
In the manifest file add android:configChanges = "orientation|screenSize"
to the activity tag.
For ex:
<activity
android:name=".dummyActivity"
android:configChanges = "orientation|screenSize"/>
If you want to handle orientation changes manually you can do so by overriding the onConfigurationChanged() method in Activity.
For more info refer Handling Configuration Changes
add this to the manifest
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
If configChanges contains uiMode, remove it. If you don't want to uninstall uiMode, you can update these libraries.
androidx.appcompat:appcompat:1.2.0-rc01
androidx.core:core:1.3.2
I want to make a new input method with no actual keyboard.
It should stay active (after being enabled by user) always but not be the default keyboard. Because it will not have any visual keyboard and user will still be able to use the default keyboard as he/she selects.
I will trigger it on demand from a network command. Is this possible ?
It should be possible, because for example Android TV remote or Shield TV remote can do this.
But I couldn't find how to do it. When I create a normal input method, it only works if I select it as the default input method.
<service android:name="SoftKeyboard"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
<meta-data android:name="android.view.im" android:resource="#xml/method" />
</service>
This is the part from manifest file. Is it possible to make it work without selecting it as the default input method ?
As a second, additional input method …
I could not find a solution which could live together with the original leanback keyboard.
So, I found an example Leanback keyboard code , injected my rest API in it.
Now I have the leanback keyboard modified to make what I want.
I have a RingtonePreference nested inside 2 PreferenceScreen declared as:
<PreferenceScreen
//other preferences
<PreferenceScreen
//other preferences
<RingtonePreference
android:key="ringtone"
android:title="#string/ringtone_title"
android:summary="#string/sipringtone_ringtone_summary"
android:ringtoneType="ringtone" />
/>
/>
The PreferenceFragment is nested inside a ActivityGroup as such. The path to the fragment is as followed:
MainActivity(TabActivity)->Activity1(ActivityGroup)->Activity2(Activity)->PreferenceFragment
I did not write this code but am picking off where someone left off. The dialogs from clicking every preference was crashing the app because it did not like the context of Activity2. This was an ActivityGroup related issue that was resolved by forcing the context of each preference to the context of Activity1.
EditPreferences, ListPreferences, and CheckPreferences all worked as intended but RingtonePreference is giving me a lot of trouble. Although the dialog pops up to let me choose the selection of ringtones, it does not save the setting.
Selecting a ringtone from the list and pressing the OK button does not trigger onPreferenceChange() or onSharedPreferenceChanged(). I tried creating a custom RingtonePreference and overriding onSaveRingtone() but that did not get called at all. However, other methods like onPrepareRingtonePickerIntent() and onRestoreRingtone() did get called. I tried a bunch of other options that were mentioned on stack overflow but had no luck. I'm running out of ideas to get RingtonePreference to work and think starting my own ringtone picker using RingtoneManager is the best alternative. If anyone could give me some advise on how to get RingtonePreference to work then that'll be awesome.
Edit: I believe this is a context problem but I can't find out how to solve it yet.
I was unable to get the RingtonePreference to work but I did find some new details and an alternative. RingtonePreference looks like it starts a new activity for the dialog. If you have launchmode=singleInstance, that will mess up the RingtonePreference because you're starting that activity on a different Task stack. Using launchmode=singleTask or removing the launchmode could solve your problem, but not for me entirely (but I still needed launchmode to not be equal to singleInstance). My solution was to add the preference manually in java code. The steps were
1) Find your preference screen
2) Make a preference
3) Set your preference details, i.e. title & summary
4) (Optional) Arrange the order of your preference (google the setOrder function for preference)
5) Set the onPreferenceCLickerListener to the preference you created
6) Inside onPreferenceClick, Launch the ringtone picker dialog configured by RingtoneManager and start the activity from where ever you want.
7) Add the preference to your preference screen chosen in step 1.
8) On the activity/fragment where you started the ringtone picker, override on onActivityResult() and handle the chosen ringtone.
Good luck!
kyrax's answer seems appropriate, although I didn't want to go through all the mess of creating a Preference programmatically and then inserting it that way.
To solve this problem, I started off with a complete XML and then I simply added the OnPreferenceChangeListener to the RingtonePreference. This can be done from your PreferenceFragment:
Preference notificationSoundPref = findPreference("ringtone);
notificationSoundPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// do what you need here
return true;
}
});
Is there a way to modify an Android app's header programatically? Maybe even adding a custom view with an image in it? I'm talking about the gray bar at the top of an app, whose text can be modified via an app's Mainfest.xml with the label attribute of the activity:
<activity android:name=".ProgramTracks" android:label="#string/app_name">
</activity>
Is there some way to, for a lack of a better word, mess with that?
Already discussed here.
You can add a custom header inside your activitys onCreate().
Write an usual xml layout and call
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.window_title);
where R.layout.window_title is your custom layout.
Just wondering if anyone has seen this problem and knows what might be wrong. I've constructed something of a library it has on the main page where you select A, B, C ... etc. and then it opens a page with buttons for whichever your choice is. Now the problem is when I load my app onto my phone it has one app button for the whole app and then it has one button for each A, B, C... etc .classes as in i can click on any of those and it opens directly from the phones menu. Its like the menu has been spammed and i don't think people would appreciate that. Anyone have any idea what it might be. Ive made an application that has a library type thing in it before and this problem never occurred.
Remove the MAIN and LAUNCHER intents from those other activities.
http://developer.android.com/guide/topics/intents/intents-filters.html
Activities that can initiate
applications have filters with
"android.intent.action.MAIN" specified
as the action. If they are to be
represented in the application
launcher, they also specify the
"android.intent.category.LAUNCHER"
category:
<intent-filter . . . >
<action android:name="code android.intent.action.MAIN" />
<category android:name="code android.intent.category.LAUNCHER" />
</intent-filter>
Also, work on your accept rate.