Duplicate pinned shortcut using Shortcut Manager - java

I am trying to create a pinned shortcut on the homescreen of my using ShortcutManager. I am able to create the pinned shortcut using the following code:
Intent i = new Intent();
i.setAction(Intent.ACTION_VIEW);
i.setData(Uri.parse("www.google.com"));
if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)){
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(context, "#1")
.setIntent(i)
.setShortLabel("label")
.setIcon(IconCompat.createWithResource(context, R.drawable.ic_launcher))
.build();
ShortcutManagerCompat.requestPinShortcut(context, shortcutInfo, null);
}else{
L.v("Shortcut", "Pinned shortcuts are not supported!");
}
I am facing two issues:
There is no check to handle duplicate shortcuts. Every time I click on the button to create a shortcut, it creates a shortcut every single time and the home screen is getting filled by these shortcuts. Is there any way to check whether the shortcut already exists like:-
Intent i = new Intent();
i.setAction(Intent.ACTION_VIEW);
i.setData(Uri.parse("www.google.com"));
Intent installer = new Intent(); installer.putExtra("android.intent.extra.shortcut.INTENT", i); installer.putExtra("android.intent.extra.shortcut.NAME", "Shortcut name"); installer.putExtra("android.intent.extra.shortcut.ICON_RESOURCE", Intent.ShortcutIconResource.fromContext(getApplicationContext() , R.drawable.ic_launcher));
installer.putExtra("duplicate", false);
installer.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
sendBroadcast(installer);
The problem with this piece of code is that it is not working in android 8.0 and above but it handles duplication of shortcut correctly using the following code :-
installer.putExtra("duplicate", false);
I want to achieve the same using Shortcut Manager
When a shortcut is created using Shortcut Manager, the icon is duplicated like
I have looked at the solution provided here but no luck so far:-
Strange app icon duplication in pinned shortcut (Android O)
Any ideas??

You can get all current shortcuts by calling
List<ShortcutInfo> currPinned = shortcutManager.getPinnedShortcuts();
then add to Map or Set and iterate over them and if its already exist dont add it again
if (currPinned != null) {
for (ShortcutInfo shortcut: currPinned) {
currPinnedMap.put(shortcut.getId(), shortcut);
}
}
....
//iterate over you "new shortcuts" and check if the present already
if (currPinnedMap.containsKey(id)) {
continue;
}
// add really new ones

fun isPinnedShortcutsExits(context: Context, id: String): Boolean {
return when {
Build.VERSION.SDK_INT >= 30 -> {
context.getSystemService(ShortcutManager::class.java)
.getShortcuts(ShortcutManager.FLAG_MATCH_PINNED)
.any { it.id == id }
}
Build.VERSION.SDK_INT >= 25 -> {
context.getSystemService(ShortcutManager::class.java)
.pinnedShortcuts
.any { it.id == id }
}
else -> false
}
}
or
ShortcutManagerCompat.getShortcuts(this, ShortcutManagerCompat.FLAG_MATCH_PINNED)
.any { it.id == "xxx" }

Related

Shared Preferences Not working over multiple contexts

Put into shared preferences code:
PreferenceManager.getDefaultSharedPreferences(Bookmarks.this).edit()
.putString("togoto", link).apply();
String togoto = PreferenceManager.getDefaultSharedPreferences(Bookmarks.this)
.getString("togoto", "no");
Toast.makeText(Bookmarks.this, "Will go to "+togoto, Toast.LENGTH_SHORT).show();
setContentView(R.layout.activity_proxy_browser);
Intent myIntent = new Intent(Bookmarks.this, ProxyBrowserActivity.class);
startActivity(myIntent);
Get from shared prferences (In other context):
String togoto = PreferenceManager.getDefaultSharedPreferences(ProxyBrowserActivity.this).getString("togoto", "nogo");
Toast.makeText(ProxyBrowserActivity.this, "1 Going to "+togoto, Toast.LENGTH_SHORT).show();
if (togoto != "no") {
Toast.makeText(ProxyBrowserActivity.this, "Going to "+togoto, Toast.LENGTH_SHORT).show();
PreferenceManager.getDefaultSharedPreferences(ProxyBrowserActivity.this)
.edit().putString("togoto", "no").apply();
} else {
// no shared preferences
}
This does not appear to work and togoto returns no on the other context. How do I allow it to work over multiple contexts?
Please use
getSharedPreferences(KEY, MODE_PRIVATE) rather than
PreferenceManager.getDefaultSharedPreferenceManager.
Your code is fine when you replace this.
If u create a default SharedPreference, it' name is context.getPackageName() + "_preferences". And getDefaultSharedPreferences get that. When u set a name like "MyApp_preferences", getDefaultSharedPreferences will find nothing. Use getSharedPreferences.

how can i get to the main file directory on android 10 and 11

I have a problem like this and I could not find a solution. my problem is Now, besides the files I created in my application, I also need to access the files in the main directory. The code I use for this is as follows. When I press the back button it goes to the previous folder.
here is my code
public void DosyaGeri(View view) {
String yol = ((TextView) findViewById(
R.id.txtKmlDosyaKonumu)).getText().toString();
String android = "/storage/emulated/0/";
String atlama="/storage/emulated/0/Android/data/com.LiderBilgisayarYazilim.cepmap/files/";
// boolean defolt= yol == "/storage/emulated/0/";
if (File.separator.compareTo(yol) == File.separator.compareTo(android)) {
finish();
startActivity(new Intent(this, Harita.class));
return;
}
else if(File.separator.compareTo(yol) == File.separator.compareTo(atlama)){
yol = android;
DosyaListesiOlustur(yol);
}
else {
yol = yol.substring(0,
yol.substring(0, yol.length() - 2).lastIndexOf("/")) +
File.separator;
DosyaListesiOlustur(yol);
}
}
but this code does not work on xiaomi devices with android 10 or higher. The reason is that it uses a different directory instead of "storage / emulated / 0 /". and it gives access permission error to this directory. how can i solve this.

Java gstreamer linking two textoverlay elements is not working

I have a rtsp player application written in java and built on top of gstreamer 1.When I try to display a text on top of the playing video with only one textoverlay element in the pipeline it is working fine.But I need to display different texts on all the corners of the window.
The first think I though was chaining overlay elements which actually worked from command line with gst-launch-1.0 as follows;
gst-launch-1.0 -v rtspsrc location=rtsp://10.0.5.41:8554 ! rtpjitterbuffer ! rtph264depay ! vaapiparse_h264 ! vaapidecodebin ! textoverlay text = "live video" halignment=left ! textoverlay text="action camera 1" ! xvimagesink
When I try to construct the same pipeline with java as follows;
this.sourceElement = ElementFactory.make(RTSP_SOURCE, RTSP_SOURCE);
final Element videoQueue = ElementFactory.make(QUEUE, QUEUE);
final Element videoDepay = ElementFactory.make(RTP_H264_DEPAY, RTP_H264_DEPAY);
final Element videoParser = ElementFactory.make(VAAPI_H264_PARSE, VAAPI_H264_PARSE);
final Element videoDecoder = ElementFactory.make(VAAPI_DECODE, VAAPI_DECODE);
videoTypeOverlay = ElementFactory.make(TEXT_OVERLAY, TEXT_OVERLAY);
videoSourceOverlay = ElementFactory.make(TEXT_OVERLAY, TEXT_OVERLAY);
sinkElement = ElementFactory.make(XV_IMAGE_SINK, XV_IMAGE_SINK);
pipe.addMany(sourceElement, videoQueue, videoDepay, videoParser, videoDecoder, videoSourceOverlay, videoTypeOverlay, sinkElement);
Element.linkMany(videoQueue, videoDepay, videoParser, videoDecoder, videoSourceOverlay, videoTypeOverlay, sinkElement);
sourceElement.connect((Element.PAD_ADDED) (element, pad) -> {
if (pad.isLinked()) {
return;
}
Caps caps = pad.getCaps();
if (caps.size() > 0) {
String mediaType = caps.getStructure(0).getString("media");
if ("video".equalsIgnoreCase(mediaType)) {
pad.link(videoQueue.getStaticPad("sink"));
}
}
});
#Override
public void play(PlaySettings playSettings) {
videoTimeOverlay.set("text", text);
videoTimeOverlay.set("valignment", valign);
videoTimeOverlay.set("halignment", halign);
...
}
I get a blank canvas.
The only way to make application at least working is to remove one of the overlays from linkMany and addMany lines as follows;
pipe.addMany(sourceElement, videoQueue, videoDepay, videoParser, videoDecoder, videoSourceOverlay, sinkElement);
Element.linkMany(videoQueue, videoDepay, videoParser, videoDecoder, videoSourceOverlay, sinkElement);
So how can I put more than one static overlay strings on video canvas?
I solved this problem by creating a Bin element and the two overlay elements are wrapped in it.
The method below is a working code example for creating Bin container element with ghost pads.
private Bin createTextOverlayBin() {
Bin textOverlayBin = new Bin();
videoTypeOverlay = ElementFactory.make(TEXT_OVERLAY, "video-type-overlay");
Optional<Pad> textOverlaySinkPad = playIdOverlay.getSinkPads().stream().filter(pad -> pad.getName().equals("video_sink")).findAny();
Optional<Pad> textOverlaySrcPad = videoTypeOverlay.getSrcPads().stream().filter(pad -> pad.getName().equals("src")).findAny();
if (textOverlaySinkPad.isPresent() && textOverlaySrcPad.isPresent()) {
textOverlayBin.add(playIdOverlay);
textOverlayBin.add(videoTypeOverlay);
GhostPad ghostSinkPad = new GhostPad("sink", textOverlaySinkPad.get());
textOverlayBin.addPad(ghostSinkPad);
GhostPad ghostSrcPad = new GhostPad("src", textOverlaySrcPad.get());
textOverlayBin.addPad(ghostSrcPad);
playIdOverlay.link(videoTypeOverlay);
} else {
LOGGER.error("Video text overlay element creation is failed!");
}
return textOverlayBin;
}

Toggle todo items completed using sbt java api

I'm trying to toggle todo items in IBM Connections to complete/incomplete using the SBT Java API.
I manage to set the todo item to complete, but how do I change it back to incomplete?
todoNode = activityService.getActivityNode( "856b9450-b3d2-4b41-a198-46feeb3772a8" );
System.out.println("Title " + todoNode.getTitle());
if ( todoNode.getCategoryFlagCompleted() == null) {
List<String> flags = new java.util.ArrayList();
flags.add("Completed");
todoNode.setFlags(flags);
}
activityService.updateActivityNode(todoNode);
Many thanks
From Connections REST API documentation:
To complete an activity, add this flag. If it is not present, the activity is not completed.
So, to mark an activity as incomplete again just update the ActivityNode without adding the "Completed" flag.
todoNode = activityService.getActivityNode( "856b9450-b3d2-4b41-a198-46feeb3772a8" );
System.out.println("Title " + todoNode.getTitle());
if ( todoNode.getCategoryFlagCompleted() != null) {
todoNode.setFlags(new java.util.ArrayList());
}
activityService.updateActivityNode(todoNode);
Just ran into same problem, however it seems you can use empty flag to get it to work.
todoNode = activityService.getActivityNode( "856b9450-b3d2-4b41-a198-46feeb3772a8" );
System.out.println("Title " + todoNode.getTitle());
if ( todoNode.getCategoryFlagCompleted() == null) {
List<String> flags = new java.util.ArrayList();
flags.add("");
todoNode.setFlags(flags);
}
activityService.updateActivityNode(todoNode);
Not sure if it works in Java tho, cause i use API in JSSS.
What's more, this solution will delete other flags like "Deleted".
You should check for them using getCategoryFlagDelete() to recreate activity "flag field" properly.

retrieve required features of a specific app

i'm tring to get all required features of specific app. i wrote this code
mPackageInfo = getPackageManager().getPackageInfo(packageName, 0);
mFeatures = mPackageInfo.reqFeatures;
if(mFeatures != null) {
for(FeatureInfo feature : mFeatures) {
mString.append(feature.name);
}
}
else {
Log.d("test", "error");
}
mFeatures is FeatureInfo[] variable. mString is StringBuffer type variable. in my logcat i see error. why? how can i solve?
Replace 0 in your getPackageInfo() call with PackageManager.GET_CONFIGURATIONS.

Categories