How to get the icon of other applications (Android) - java

What I'm doing is getting a list of all the current running processes on the phone. Which I have done by,
private List<RunningAppProcessInfo> process;
private ActivityManager activityMan;
...
activityMan = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
process = activityMan.getRunningAppProcesses();
this works fine. When I call the processName field like
process.get(i).processName;
I get a name like com.android.mail for example.
what I'm trying to do is use this to get access to that application so I can display its icon to the user, but I cant find anything that lets me do this. Is there something that can help me?
I'm testing this app on my hero so the api level is 3 (android 1.5).
Thanks.

Ok, I figured out how to do it. In case your curious this is what I did.
private PackageManager pk;
pk = getPackageManager();
....
pk.getApplicationIcon(process.get(i).processName)
Thanks.

try this way make a class called packageinformation:
public class PackageInformation{
private Context mContext;
public PackageInformation(Context context){
mContext=context;
}
class InfoObject {
public String appname = "";
public String pname = "";
public String versionName = "";
public int versionCode = 0;
public Drawable icon;
public void InfoObjectAggregatePrint() {//not used yet
Log.v(appname,appname + "\t" + pname + "\t" + versionName + "\t" + versionCode);
}
}
private ArrayList getPackages() {
ArrayList apps = getInstalledApps(false); /* false = no system packages */
final int max = apps.size();
for (int i=0; i
public ArrayList<InfoObject> getInstalledApps(boolean getSysPackages) {
ArrayList<InfoObject> res = new ArrayList<InfoObject>();
List<PackageInfo> packs = mContext.getPackageManager().getInstalledPackages(0);
for(int i=0;i<packs.size();i++) {
PackageInfo p = packs.get(i);
if ((!getSysPackages) && (p.versionName == null)) {
continue ;
}
InfoObject newInfo = new InfoObject();
newInfo.appname = p.applicationInfo.loadLabel(mContext.getPackageManager()).toString();
newInfo.pname = p.packageName;
newInfo.versionName = p.versionName;
newInfo.versionCode = p.versionCode;
newInfo.icon = p.applicationInfo.loadIcon(mContext.getPackageManager());
res.add(newInfo);
}
return res;
}
}
tuck this away somewhere and now to access the info from your working class do this:
PackageInformation androidPackagesInfo=new PackageInformation(this);
ArrayList<InfoObject> appsData=androidPackagesInfo.getInstalledApps(true);
for (InfoObject info : appsData) {
Toast.makeText(MainActivity.this, info.appname,2).show();
Drawable somedrawable=info.icon;
}

Since Android 3.0 you might want to get a bigger launcher icon that you can't get the way you described. If so, perhaps my answer to question below can help you: Getting App Icon in Android

While packagemanager.getApplicationIcon(pkagename) works for some apps but not for all.
Found better answer here:
how to get running applications icon on android programmatically
Uses:
Drawable ico=getApplicationInfo(packagemanager,PackageManager.GET_META_DATA).loadIcon(getPackageManager());

Related

In-App billing v3, getPurchases() and android.test.purchased

Presumably after xx.may.2019 method getPurchases() stopped returning the test item "android.test.purchased".
Just stopped working, that's all. The client code has not changed.
This behavior is observed on the three test devices. Attempts were made to clear the cache.
When i try to make a purchase:
private static final String IN_APP_BILLING = "inapp";
private final String packageName = context.getPackageName();
private String rewardId = "android.test.purchased";
private static final int BILLING_VER = 3;
......
try {
buyIntentBundle = getBillingService().getBuyIntent(BILLING_VER, packageName, rewardId, IN_APP_BILLING, null);
}
catch (RemoteException e)
{
e.printStackTrace();
}
Receive BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED.
Ok...
Then call
String consumToken = IN_APP_BILLING + ":" + packageName + ":" + rewardedId;
try {
getBillingService().consumePurchase(BILLING_VER, packageName, consumToken);
......
method is successfully completed.
After that, the purchase is successfully made.
But the
try {
Bundle purchases = getBillingService().getPurchases(BILLING_VER, packageName, IN_APP_BILLING, null);
.....
method does not return a test item.
Uploaded alpha version in Google Play with real IDs - everything good works... The only refund are updated in the cache during the day(can be up to 3 days).
P.S. Sorry for bad English.

Android Java USB serial communication plugin for Unity not running

I created a Java plugin that utilizes the UsbManager devices to communicate with a specified serial device. I'm using Android Studio to run the plugin and can write to the proper device, but I don't understand how to integrate my code with Unity. I pass the Context in the constructor so I can create the UsbManager, but I don't know how to this in Unity or if there's another way to get the Context.
What's the proper way to pass the Context from Unity to my plugin? I'm also not sure if my function is working in Unity, because I don't know if permissions are needed for USB as well in the manifest file.
Unity Code:
void Start()
{
ajc = new AndroidJavaObject("com.company.dg.USBController");
int connected = ajc.Call<int>("startUSB");
}
Java Code:
public class USBController {
private Context context;
private static final String ACTION_USB_PERMISSION = "com.company.dg.USB_PERMISSION";
private final int BAUD_RATE = 19200;
private int bytesRead;
private byte[] readBuffer;
private UsbManager usbManager;
private UsbDeviceConnection connection;
private UsbSerialDevice serial;
private UsbDevice dg = null;
public USBController(Context context){
this.context = context;
}
public int startUSB(){
//usbManager = (UsbManager) context.getSystemService(context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
UsbDevice dg = null;
if(deviceList.size() == 0){
return -2;
}
// 1st and only device
dg = deviceList.values().iterator().next();
if(dg != null){
PendingIntent pi = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(dataglove, pi);
UsbDeviceConnection connection = usbManager.openDevice(dataglove);
UsbSerialDevice serial = UsbSerialDevice.createUsbSerialDevice(dg, connection);
serial.open();
serial.setBaudRate(BAUD_RATE);
serial.setDataBits(UsbSerialInterface.DATA_BITS_8);
serial.setStopBits(UsbSerialInterface.STOP_BITS_1);
serial.setParity(UsbSerialInterface.PARITY_NONE);
serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serial.read(callback);
} else {
return -1;
}
return 0;
}
private UsbSerialInterface.UsbReadCallback callback = new UsbSerialInterface.UsbReadCallback() {
#Override
public void onReceivedData(byte[] data) {
bytesRead = data.length;
readBuffer = data;
}
};
What's the proper way to pass the Context from Unity to my plugin?
C# side:
Your USBController class has a constructor that takes Context as an argument. Before calling the startUSB function, obtain the Unity Context then send it to the constructor when you're creating an instance of USBController.
Get Unity Context:
AndroidJavaClass unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject unityActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject unityContext = unityActivity.Call<AndroidJavaObject>("getApplicationContext");
Send the Context to your Java code when creating an instance of it:
ajc = new AndroidJavaObject("com.bebopsensors.dg.USBController", unityContext);
Now, you can call your startUSB function:
int connected = ajc.Call<int>("startUSB");
Java Side:
In your startUSB function, you can now use the Context with the getSystemService. I noticed you commented that out. Note that the context.USB_SERVICE should be Context.USB_SERVICE. The c in Context should be capitalized.
public int startUSB()
{
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
....
....
}
Don't know if permissions are needed for USB as well in the manifest
file.
Not really sure about that but I believe that calling the requestPermission function which you did should be enough to handle that. If this is not working then I suggest you test your Java program in Android only and Without Unity to see if it's working. If it works there, the solution I suggested should also work.

ListView error: "Java.Lang.RuntimeException: Canvas: trying to use a recycled bitmap"

I'm using FFImageLoading for developing a Xamarin.Forms apps on iOS and Android. On iOS it works fine. But on Android, it always crashes after a while.
The app uses a simple ListView with "CachedImage" elements in each cell.
My app crashes with this error: "Java.Lang.RuntimeException: Canvas: trying to use a recycled bitmap"
I use FFImageLoading in a simple Listview with a custom Cell.
This is the crash log:
Java.Lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap#f41b99a
...
at java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap#f41b99a
at at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1270)
at at android.graphics.Canvas.drawBitmap(Canvas.java:1404)
at at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:544)
at at android.widget.ImageView.onDraw(ImageView.java:1244)
at at android.view.View.draw(View.java:16178)
at at android.view.View.updateDisplayListIfDirty(View.java:15174)
at at android.view.View.draw(View.java:15948)
at at android.view.ViewGroup.drawChild(ViewGroup.java:3609)
at at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3399)
at at android.view.View.updateDisplayListIfDirty(View.java:15169)
... (cut)
My XAML main Page:
<ContentPage
xmlns:cells="clr-namespace:MyApp;assembly=MyApp"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.SamplePage"
Title="SamplePage">
<ContentPage.Content>
<ListView
x:Name="MediaItemsListView"
BackgroundColor="Transparent"
SeparatorVisibility="None"
HorizontalOptions="Center"
VerticalOptions="Start"
Margin="15,0,0,0"
RowHeight="255">
<ListView.ItemTemplate>
<DataTemplate>
<cells:CellEvento />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
This is the main Page codebehind:
public partial class SamplePage : ContentPage
{
public SamplePage ()
{
InitializeComponent ();
MediaItemsListView.ItemsSource = DataProvider.GetMediaItems ();
}
}
This is the custom Cell XAML:
<ViewCell x:Class="MyApp.CellEvento"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:MyApp="clr-namespace:MyApp;assembly=MyApp">
<AbsoluteLayout WidthRequest="344"
HeightRequest="244"
BackgroundColor="White" >
<ffimageloading:CachedImage x:Name="ImageView"
AbsoluteLayout.LayoutBounds="0,48,144,152"
AbsoluteLayout.LayoutFlags="None"
DownsampleToViewSize="true"
LoadingPlaceholder="PlaceholderEventBadgePhotoGrayS.png" />
<ffimageloading:CachedImage x:Name="UserThumbnailView"
WidthRequest="24"
HeightRequest="24"
AbsoluteLayout.LayoutBounds="298,211,24,24"
AbsoluteLayout.LayoutFlags="None"
DownsampleToViewSize="true"
LoadingPlaceholder="PlaceholderEventBadgePhotoGrayS.png">
<ffimageloading:CachedImage.Transformations>
<fftransformations:CircleTransformation />
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
</AbsoluteLayout>
</ViewCell>
This is the custom cell codebehind:
public partial class CellEvento : ViewCell
{
public CellEvento ()
{
InitializeComponent ();
}
protected override void OnBindingContextChanged ()
{
base.OnBindingContextChanged ();
var mediaItem = BindingContext as MediaItem;
if (mediaItem != null)
{
ImageView.Source = mediaItem.ImagePath ?? "";
UserThumbnailView.Source = mediaItem.AvatarPath ?? "";
}
}
}
This is the data provider class:
public static class DataProvider
{
public static ObservableCollection<MediaItem> GetMediaItems ()
{
ObservableCollection<MediaItem> items = new ObservableCollection<MediaItem> ();
int counter = 0;
for (int index = 0; index < 20; index++) {
for (int i = 0; i < 20; i++) {
var item = new MediaItem (
"Image n." + counter,
GetRandomImageUrlFlickr (288, 304),
GetRandomAvatarPhotoUrlFlickr (120, 120),
counter);
items.Add (item);
counter++;
}
}
return items;
}
public static string GetRandomImageUrlFlickr (int width, int height)
{
return string.Format ("http://loremflickr.com/{1}/{2}/nature?filename={0}.jpg", Guid.NewGuid ().ToString ("N"), width, height);
}
public static string GetRandomAvatarPhotoUrlFlickr (int width, int height)
{
return string.Format ("http://loremflickr.com/{1}/{2}/girl,face/all?filename={0}.jpg", Guid.NewGuid ().ToString ("N"), width, height);
}
}
And this is the mediaitem class:
public class MediaItem
{
public string Name { get; set; }
public int Index { get; set; }
public string ImagePath { get; set; }
public string AvatarPath {get; set; }
public MediaItem (string Name, string imagePath, string string avatarPath, int counter)
{
this.ImagePath = imagePath;
this.AvatarPath = avatarPath;
this.Name = counter.ToString ();
this.Index = counter;
}
public override string ToString ()
{
return string.Format ("[MediaItem: Name={0}]", Name);
}
}
It is a pretty basic setup of a Xamarin.Forms app. The code is almost all in the shared part of the App. As I said the app works fine on iOS. But on Android it crashes.
The Droid project in my Xamarin Studio IDE was pretty basic. I just added the placeholder png to the drawable, and added this initialization code to the MainActivity OnCreate method:
//FFImage platform specific initialization code for Droid------
FFImageLoading.Forms.Droid.CachedImageRenderer.Init ();
var circlee = new FFImageLoading.Transformations.CircleTransformation ();
var config = new FFImageLoading.Config.Configuration () {
VerboseLogging = true,
VerbosePerformanceLogging = true,
VerboseMemoryCacheLogging = true,
VerboseLoadingCancelledLogging = true,
Logger = new CustomLogger (),
MaxMemoryCacheSize = 10,
};
ImageService.Instance.Initialize (config);
//-----------------------------------
And of course I tried to remove the CircleTrasformation, but it makes no difference. After a few seconds of scroll, the app crashes.
The Android emulators I tried are many: official emulator of a Nexus 5 (standard setup, v19), Nexus 5 (with android v23), and Genymotion Nexus 5 (with android v19), and some more. All gives the same result: crash when scrolling after 2-5 seconds.
What is puzzling me is that, differently from other questions with similar errors here on SO, I don't explicitly call any Recycle command. I let the Listview class handle the recycling by itself.
What I'm missing here?
Any help is appreciated, thanks.
UPDATE: I opened the issue on the ffimageload github repo:
https://github.com/luberda-molinet/FFImageLoading/issues/297

Sounds working on Lollipop but not on kitkat or older versions

I made a method I'm using in onCreate, it's called loadSounds, and depending on the version I use the SoundPool Builder or the deprecated version if it's an older version of Android......But sounds only work on Lollipop devices......What could be wrong....the app runs in both versions.....The variable that holds the SoundPool is declared outside of onCreate as an object attribute private static SoundPool mySounds;
Thanks in advance!!!
private void loadSounds(){
if(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP) {
AudioAttributes audioAttributes = new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN).setUsage(AudioAttributes.USAGE_GAME).build();
mySounds = new SoundPool.Builder().
setMaxStreams(10).
setAudioAttributes(audioAttributes).
build();
correctAnswerID = mySounds.load(this, R.raw.correctanswer, 1);
incorrectAnswerID = mySounds.load(this, R.raw.incorrectanswer, 1);
}
else
{
mySounds= new SoundPool(10, AudioManager.USE_DEFAULT_STREAM_TYPE,1);
correctAnswerID = mySounds.load(this, R.raw.correctanswer, 1);
incorrectAnswerID = mySounds.load(this, R.raw.incorrectanswer, 1);
}
}
The method that uses the sounds is(if the answer is correct plays the correctanswer mp3, otherwise it plays the wronganswer mp3) :
if(selectedAnswer.equals(currentAnswer) || isEnharmonic ){
correctAnswers+=1;
reproduceAnswerSound("Correct");
}
else
{
incorrectAnswers+=1;
reproduceAnswerSound("Incorrect");
}
and the method that reproduce the sounds is like this:
private void reproduceAnswerSound(String type){
if(type.equals("Correct")){
mySounds.play(correctAnswerID,1,1,1,0,1);
}else if(type.equals("Incorrect"))
{
mySounds.play(incorrectAnswerID,1,1,1,0,1);
}
}

YouTube API: How to obtain text of Related videos, given a video's URL?

I have a pretty straight forward task -
Given the URL of a video, I want to extract information of its Related videos (and by information I mean their Title, Tags, Description).
I use Java version of the YouTube API and couldn't find out how to do that quickly. Also, this site: https://developers.google.com/youtube/2.0/developers_guide_java provides some information. The code they provide is:
if (videoEntry.getRelatedVideosLink() != null) {
String feedUrl = videoEntry.getRelatedVideosLink().getHref();
VideoFeed videoFeed = service.getFeed(new URL(feedUrl), VideoFeed.class);
printVideoFeed(videoFeed, true);
}
I don't know how to create a videoEntry given only the URL..
You can use this:
class YouTubeVideoInfo {
private String channel;
private String url;
private long views;
private int comments;
private int ratings;
private int likes;
private int dislikes;
private String thumbnail;
private String title;
.....
}
public static final String YOUTUBE_GDATA_SERVER = "http://gdata.youtube.com";
public static final String USER_FEED_PREFIX = YOUTUBE_GDATA_SERVER + "/feeds/api/users/";
public static final String UPLOADS_FEED_SUFFIX = "/uploads";
...............
public YouTubeVideoInfo getVideoInfo(YouTubeService service, String channel, String url) {
VideoFeed videoFeed = service.getFeed(
new URL(USER_FEED_PREFIX + channel + UPLOADS_FEED_SUFFIX), VideoFeed.class);
List<VideoEntry> videoEntries = videoFeed.getEntries();
for (VideoEntry videoEntry : videoEntries) {
YouTubeMediaGroup mediaGroup = videoEntry.getMediaGroup();
if (mediaGroup != null && mediaGroup.getPlayer() != null && videoEntry.getTitle() != null) {
if (url.equals(mediaGroup.getPlayer().getUrl())) {
String title = videoEntry.getTitle().getPlainText();
MediaKeywords keywords = mediaGroup.getKeywords();
MediaPlayer mediaPlayer = mediaGroup.getPlayer();
final YtStatistics statistics = videoEntry.getStatistics();
final YouTubeVideoInfo videoInfo = new YouTubeVideoInfo(channel,
mediaPlayer.getUrl(), statistics != null
? statistics.getViewCount() : 0);
if (videoEntry.getComments() != null
&& videoEntry.getComments().getFeedLink() != null)
videoInfo.comments =
videoEntry.getComments().getFeedLink().getCountHint();
final Rating rating = videoEntry.getRating();
if (rating != null)
videoInfo.ratings = rating.getNumRaters();
final YtRating ytRating = videoEntry.getYtRating();
if (ytRating != null) {
videoInfo.likes = ytRating.getNumLikes();
videoInfo.dislikes = ytRating.getNumDislikes();
}
final List<MediaThumbnail> thumbnails = mediaGroup.getThumbnails();
if (!thumbnails.isEmpty())
videoInfo.thumbnail = thumbnails.get(thumbnails.size() / 2).getUrl();
if (videoEntry.getTitle() != null)
videoInfo.title = videoEntry.getTitle().getPlainText();
return videoInfo;
}
}
.... // exception handling
I have got a method to do what I intended to. I did not require name of the Channel (username that uploaded the video). All I need is a URL. YouTube has an ID corresponding to each video. For example, for the video: http://www.youtube.com/watch?v=f3q3JkNUPmI , the ID is "f3q3JkNUPmI" (without the quotes). So, all you need to do is to create a String containing the feed link that you want to get. This can be created as:
String Video_Related_Feed="https://gdata.youtube.com/feeds/api/videos/f3q3JkNUPmI/related?v=2" (don't replace https with http -- it does not work)
Obviously, one can automate this .. I'm just giving the hard-coded example.
Now get the actual Feed based on this address:
VideoFeed videoFeed = service.getFeed(new URL(Video_Related_Feed), VideoFeed.class);
This feed contains VideoEntry of the Related videos (corresponding to our original URL), each of which can be accessed by a for loop:
for (VideoEntry ve : videoFeed.getEntries()) { insert your code here }
References: https://developers.google.com/youtube/2.0/reference
andhttps://developers.google.com/youtube/2.0/developers_guide_java
(sorry, I had to write last link like that because I couldn't post more than 2 URLs).
I hope this helps someone.

Categories

Resources