Google+-Package name not getting added to String[]? - android

My app is keeping a "third-party app-exclude-list" as package names in a String[] (and serializing it to the SharedPreferences using the method below). This works fine, but for some users, the Google+ isn't getting added to this list. It only happens for the Google+ app. For all I know, the G+ app isn't anything special, it's package name on Google Play is listed as com.google.android.apps.plus, which shouldn't confuse the saving-algorithm. It works fine on my own phone, so I'm stumped at what causes this, but a lot of my users have reported this as an issue :-/!
public void saveExcludedApplicationList(String[] applicationList) {
mExcludedApplicationList = applicationList;
String combined = "";
for (int i=0; i<mExcludedApplicationList.length; i++){
combined = combined + mExcludedApplicationList[i] + ";";
}
mPref.edit().putString(PREF_EXCLUDED_APPLICATION_LIST, combined).commit();
}

Turns out this had nothing to do with the way I was serializing this, but with the "Google+ Messaging" app beging distributed as the same package as G+.

Related

Get all Twitter clients from installed Applications

I'm wondering if it's feasible to list out all Twitter clients that are installed into a phone. At first, I thought this could be done by matching the package name with "Twitter". But most of the Twitter clients on Android don't have 'Twitter' name in their package name.
We can fetch application list with specific permissions but that doesn't going to help me. Fetching applications with certain custom intents probably not going to help as well, and I still have to find a way to get a list of applications that handle a custom Intent.
It doesn't seem feasible but there must be some way that could at least put me close to want I want. Anyone would like to shed some light on it?
I don't know if there is some kind of method to get "twitter client" (how we define Twitter client?).
You can fetch a list of names (the twitter clients you know) on the packages installed on devices.
final List<PackageInfo> apps = context.getPackageManager().getInstalledPackages(0);
final String separator = ";";
final String separatorVersion = "-";
//Log.i("Package list", "num:+"+apps.size());
for (PackageInfo infoApp : apps) {
for (TwitterClient tr : mapTwitterClient.values()) {
if (infoApp.packageName.contains(tr.getPackageName()) ) { //it's a Twitter client this package?
if (!twitterClients.equals("")) {
twittersClients += separator;
}
twitterClients += tr.getCommonName()+separatorVersion+infoApp.versionName;
}
}
}
You need to create the class TwitterClient which just have 2 properties(packageName and commonName) and his getters/setters.
And fill map with all TwitterClient you know (Ex: new TwitterClient("com.twitter.android","Twitter official") );
private static final HashMap<String, TwitterClient> mapTwitterClient
This method it's hard process so use smartly.

Is there an API to allow an android app to determine whether a Google Play user is a tester for the app?

I am developing a Google Play services based app. I am using the suggested BaseGameActivity superclass to inherit lots of the functionality. The user can log in via their Google account.
I wanted to provide a special preference setting for testers of the android app.
After looking in the SDK reference,
I haven't been able to find if there is any way to determine whether the logged in user is configured as a tester for the app. Is this possible?
Is there another recommended way to provide extra functionality for testers of the app related to their testing? For instance, in my game app, I want to allow the testers to reset their achievements and leaderboard entries, which I found can be done via a web service call.
Thanks
There's no such API that I know of.
The trick that I have been using, and you are welcome to use as well is to
determine whether a device is a tester device by its ANDROID_ID, and fork different
behaviors accordingly. Something like this:
static String androidId;
static boolean isTesterDevice;
boolean isTesterDevice() {
if (androidId != null) {
return isTesterDevice; // optimization: run string compares only once
}
androidId = Secure.getString(context.getContentResolver(),Secure.ANDROID_ID);
isTesterDevice = Arrays.asList(ALL_TESTER_DEVICES).contains(androidId);
return isTesterDevice;
}
Where ALL_TESTER_DEVICES is a String array containing all testers ANDROID_IDs:
static final String[] ALL_TESTER_DEVICES = {
"46ba345347f7909d",
"46b345j327f7909d" ... };
Once we have this working we can create tester specific logics inside our code:
if (isTesterDevice()) {
perform tester logic
}
We can also pass a isTester field to the backend server as part of the handshake
procedure, allowing it to perform its own set of tester handling.
This works just fine for small teams of testers. When QA teams grows larger, or
when you cannot ingerrogate some of the tester devices for their ID, we find it
useful to allow our testers to flag their identity by adding a special file to
the SDCARD. In that case isTesterDevice() will change to:
boolean isTesterDevice() {
if (androidId != null) {
return isTesterDevice; // optimization: run string compares only once
}
// check by device ID
androidId = Secure.getString(context.getContentResolver(),Secure.ANDROID_ID);
isTesterDevice = Arrays.asList(ALL_TESTER_DEVICES).contains(androidId);
if (!isTesterDevice) {
// check by tester file
File sdcard = Environment.getExternalStorageDirectory();
File testerFile = new File(sdcard.getAbsolutePath(), "I_AM_TESTER.txt");
isTesterDevice = testerFile.exists();
}
return isTesterDevice;
}
Hope it helps.

Android: Determine category of installed apps

Given the list of installed packages on an Android device, is there a way to sort the applications into categories without using a self-compiled hard-coded list of apps in categories?
For example, if the installed apps were Phone, Angry Birds & Messages, Phone & Messages might be in Communications and Angry Birds in Games.
I've seen How to get Category for each App on device on Android? yet hoped there may be a method that has come along since.
No, because apps don't have categories. Apps don't need to be installed through google play, the categories on other stores won't be the same. It may never have been installed from a store to begin with- I sideload apps all the time written by myself or friends. Th concept doesn't exist.
Not to mention Google Play categories are pretty bad- things frequently don't fall into one or the other, the descriptions are vague, and they're way too broad- they need at least 2 or 3 levels of subcategories to make them halfway usable.
There is no change API wise since the last question.
At best, you could retrieve each package name and scrape the Google Play page. However, this will fail if the app is not present on Google Play.
I also faced the same issue. The solution for the above query is stated below.
Firstly, download the Jsoup library or download the jar file.
or Add this to your build.gradle(Module: app) implementation 'org.jsoup:jsoup:1.11.3'
private class FetchCategoryTask extends AsyncTask {
private final String TAG = FetchCategoryTask.class.getSimpleName();
private PackageManager pm;
#Override
protected Void doInBackground(Void... errors) {
String category;
pm = getPackageManager();
List<ApplicationInfo> packages =
pm.getInstalledApplications(PackageManager.GET_META_DATA);
Iterator<ApplicationInfo> iterator = packages.iterator();
// while (iterator.hasNext()) {
// ApplicationInfo packageInfo = iterator.next();
String query_url = "https://play.google.com/store/apps/details?
id=com.imo.android.imoim"; //GOOGLE_URL + packageInfo.packageName;
Log.i(TAG, query_url);
category = getCategory(query_url);
Log.e("CATEGORY", category);
// store category or do something else
//}
return null;
}
private String getCategory(String query_url) {
try {
Document doc = Jsoup.connect(query_url).get();
Elements link = doc.select("a[class=\"hrTbp R8zArc\"]");
return link.text();
} catch (Exception e) {
Log.e("DOc", e.toString());
}
}
}
In return, you will get Application Company Name and category of the application

How to notify users about an Android app update?

I've built an Android app which is now on Play Market. From time to time, I make updates to it, and I'd like to let users know that a new version is available.
How can I send an update notification to the users of the app?
You do not need to do anything specific for this. Since you mentioned that you are using Google Play, the update notification is taken care of by Google Play.
You just need to update the APK with a higher versionCode and Google Play should do the rest.
Update 2020: now you can use in-app updates mechanism
Docs: https://developer.android.com/guide/playcore/in-app-updates
You can do this in a lot of ways, depending on when you want the user to be able to see that there is an update available.
If you want the user to know about the update when the app is started, just create a utility method (inside the onCreate method of your main/first Activity) that checks if a newer version is available in Google Play. If it does, display an alert dialog with a relevant message and an Intent which opens your app in Google Play when the user clicks on the positive button of the alert dialog.
If you are updating the app regularly, the user will keep getting this alert dialog every time the app is started and hence, may get irritated. Thus, this is not the best approach.
If you want the user to get a notification on the phone (and not when the user starts the app), you can use the AlarmManager class to schedule a background service which checks for an update at regular intervals. If the service finds that an upgrade is actually available, publish a notification with an intent that opens your app in Google Play.
Of course, another approach is to leave it to the OS itself. If the user has not set the "Automatically update" preference for your app, the user will get a notification regularly about an update available for your, as well as any other apps.
But not all users enable background data on their devices, so this is not completely reliable.
In the end, you must respect the users preferences. If the user does not want to automatically update the app, or does not want to see a nagging dialog box whenever he/she starts your app, don't alert the user about the update.
In my opinion, you should create a PreferenceActivity that has a preference like "Check for updates regularly", which can be set from within your app. If it is set, do the needful in your own service. May be even give the user an option to select the period after which the service will check for an update.
I hope this helps!
It is up to each phone owner if she wants to be notified on new versions by google play, and it's up to each phone's manufacturer if this is to be enabled by default.
If you however are in a situation where you "require" the user to update to the new version to be compatible with some form of protocol or you have a similar similar use case where you have a server component somewhere, you might want to notify the user of a potential version conflict in the UI based on information about what is the latest version.
This information can be grabbed directrly from google play, however as #Yahel pointed out in this question google play is a closed system with no official API, and you might need to rely on unpredictable undocumented API. There is an unofficial API library here.
This leaves only one option, which is to keep this information on your own server. If you allready have a serverside this might be trivial. Simply put the latest version in an XML file and retreive that at regular intervals from your code. If the version code is outdated, trigger the notification in your UI. Here is an example implementation for doing that.
I hope this was helpful :-)
I know this is an old question but still if people are coming here to check this question, Google is now providing official support for in-app notification for application update the full documentation can be found here
Use this : https://www.push-link.com/
Google Play will notify your users that the app has an update via the notification bar.
If you set up a notification system yourself, the likely result would be that, although the user is notified of an update sooner, when he/she goes to Google Play to install the update it will not yet be available. This is because there is a lag from the time you "publish" an app/update and the time until it appears on Play. Telling your users that there is an update when the update is unavailable would only lead to confusion and frustration.
My advice: stick with Google's update notification system and don't worry about trying to get users an update 15 minutes sooner.
Some people use Android Cloud-to-Device Messaging (C2DM) to notify their users of updates. I don't think I'd bother, since I think Google Play does a pretty good job of notifying me of updates already, and implementing C2DM adds a whole new dimension to writing an app (because it requires a server component). But maybe you want to offer your users a richer update notification than you get from Google Play.
#Davek804's answer above is wrong. android:versionCode is an integer value that represents the version of the application code, relative to other versions, so using "1.5b" there is incorrect. Use "15" (or "150") instead
Found a nice solution for your problem:
Let´s say you want to check for version updates manually on app start and notify your users for the new Update.
Step 1: Download android-market-api (not the .jar file, the full project!)
Step 2: After importing it to eclipse, write in your activity the following code:
MarketService ms = new MarketService(activity);
ms.level(MarketService.REVISION).checkVersion();
now, we need to modify MarketService.java, because it seems to be broken.
Step 3: rewrite callback method and add the following methods
protected void callback(String url, JSONObject jo, AjaxStatus status){
if(jo == null) return;
String googlePlayversion = jo.optString("version", "0");
String smartphone_version = "";
PackageInfo pInfo;
try {
pInfo = act.getPackageManager().getPackageInfo(act.getPackageName(), 0);
smartphone_version = pInfo.versionName;
} catch (NameNotFoundException e) {}
boolean new_version_avaible = compare(smartphone_version, googlePlayversion);
if(new_version_avaible){
showUpdateDialog(jo);
}
}
private static boolean compare(String v1, String v2) {
String s1 = normalisedVersion(v1);
String s2 = normalisedVersion(v2);
int cmp = s1.compareTo(s2);
String cmpStr = cmp < 0 ? "<" : cmp > 0 ? ">" : "==";
System.out.printf("result: "+"'%s' %s '%s'%n", v1, cmpStr, v2);
if(cmpStr.contains("<")){
return true;
}
if(cmpStr.contains(">")||cmpStr.contains("==")){
return false;
}
return false;
}
public static String normalisedVersion(String version) {
return normalisedVersion(version, ".", 4);
}
public static String normalisedVersion(String version, String sep, int maxWidth) {
String[] split = Pattern.compile(sep, Pattern.LITERAL).split(version);
StringBuilder sb = new StringBuilder();
for (String s : split) {
sb.append(String.format("%" + maxWidth + 's', s));
}
return sb.toString();
}
If you want to test it, modify googlePlayversion string to a higher version than your local one.
The source comparison method I used is from How do you compare two version Strings in Java?
There is also a very good approach for checking version and give user in app notification or when you want to forcefully update the application if you can decide the first connection of your app with the server.In the response of the first request you can send the current version of app stored on your server and then on client end you can take the appropriate action.
Advantages of this approach-:
1-No extra request for version no.
2-It is also applicable if you are downloading the app other than the google playstore.
3-you can also use this idea if you want to check the version at particular operation of your app ex- transaction(if you add a new payment gateway.)
Don't know if you want to walk extra miles. You can try out google appengine, which serve version number for your app and let you android app check the appengine to see if there is a new version when the application is launched. That way, it does not matter if your app is in google play market nor amazon app store nor if it is installed on the phone without those two via sideloading. It is not very hard to setup appengine just for serving your application version in json. Replace "Hello World" string with your app version name ...
This can be using a simple webservice just this is one of the way to acheive.
i.e., when ever the app launch hit that webservice with the current version of the user app and on the server you need to check whether any new version is available or not(Must maintain the newest version of the app) and send the corresponding response to the user. If any newer version is available prompt the user to download the newest version of the application and if no newest version is available then allow the user to continue.
Hope so atleast something must be useful to you.
There are two models that are basically used to tackle the issue.
Pull Based
Push Based
Its depends on the architecture or design of particular system that determines whether pull based or push mechanism is used.
For pull based model you just make one http request to concerned server regarding the new version of application. The current application version no can be saved in SQLLite in android application. This can be given to server and new version can be checked against it at the server.
For push mechanism you can use C2DM push notification service.. details of which are given at http://code.google.com/android/c2dm/
Generally when you upload a new application to Google play most users get a notification about an update, some will have the app automatically downloaded to their device, depending on the settings they have.
If you seriously want to make a notification from your app to ask them to update (so that everyone gets the notification, whatever their Google play settings are, then you will have to make a web service which returns the number of the newest version. You can then compare that inside your app and post a notification. You could use Google App Engine ( https://developers.google.com/appengine/) because that works with eclipse and java, which you probably already have.
I would not recommend this approach as it creates a lot of work for you to provide something that most users have already got.
i think this is too late but it can be help some one
public enum AppVersionUpgradeNotifier {
INSTANCE;
private static final String TAG = "AppVersionUpdateManager";
private static final String PREFERENCES_APP_VERSION = "pref_app_version_upgrade";
private static final String KEY_LAST_VERSION = "last_version";
private SharedPreferences sharedPreferences;
private VersionUpdateListener versionUpdateListener;
private boolean isInitialized;
public static synchronized void init(Context context, VersionUpdateListener versionUpdateListener) {
if (context == null || versionUpdateListener == null) {
throw new IllegalArgumentException(TAG + " : Context or VersionUpdateListener is null");
}
if (!INSTANCE.isInitialized) {
INSTANCE.initInternal(context, versionUpdateListener);
} else {
Log.w(TAG, "Init called twice, ignoring...");
}
}
private void initInternal(Context context, VersionUpdateListener versionUpdateListener) {
this.sharedPreferences = context.getSharedPreferences(PREFERENCES_APP_VERSION, Context.MODE_PRIVATE);
this.versionUpdateListener = versionUpdateListener;
this.isInitialized = true;
checkVersionUpdate();
}
private void checkVersionUpdate() {
int lastVersion = getLastVersion();
int currentVersion = getCurrentVersion();
if (lastVersion < currentVersion) {
if (versionUpdateListener.onVersionUpdate(currentVersion, lastVersion)) {
upgradeLastVersionToCurrent();
}
}
}
private int getLastVersion() {
return sharedPreferences.getInt(KEY_LAST_VERSION, 0);
}
private int getCurrentVersion() {
return BuildConfig.VERSION_CODE;
}
public void upgradeLastVersionToCurrent() {
sharedPreferences.edit().putInt(KEY_LAST_VERSION, getCurrentVersion()).apply();
}
public interface VersionUpdateListener {
boolean onVersionUpdate(int newVersion, int oldVersion);
}
}
use it on
public class MyApplication extends Application implements AppVersionUpgradeNotifier.VersionUpdateListener {
#Override
public void onCreate() {
super.onCreate();
AppVersionUpgradeNotifier.init(this,this);
}
#Override
public boolean onVersionUpdate(int newVersion, int oldVersion) {
//do what you want
return true;
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1.5b"
android:versionName="1.5b">
When you re-upload your app to Google Play, if these two attributes have been changed from the previous upload, Google Play will automatically send notifications to users who have installed your app. This is the AndroidManifest file.

How can I do an Amazon App Store search using an Intent and filter it by developer name?

Is there a way to start an Intent on the Kindle Fire that will cause the AppStore app to open and display all the apps for a certain developer? For instance, on a phone/tablet with the Android Market installed, I can do this:
Intent otherApps = new Intent(Intent.ACTION_VIEW,Uri.parse("market://search?q=pub:\"" + developerName + "\""));
activity.startActivity(otherApps);
And show all my apps in the Android Market. Can I do that with the Amazon App Store? If so, how? I've tried that Intent with other seemingly valid names (such as "ZeptoLab") and I don't get any filtering. It just drops me in the full unfiltered App Store. Looking up a specific app with "market://details?id=package.name" does seem to work.
From https://developer.amazon.com/help/faq.html#Marketing:
To point to your app for marketing purposes use the URL http://www.amazon.com/gp/mas/dl/android?p=packagename (where packagename is your app package name).
If you want to link to the list of all your applications on the Amazon Appstore use the URL http://www.amazon.com/gp/mas/dl/android?p=packagename&showAll=1.
e.g. http://www.amazon.com/gp/mas/dl/android?p=com.rovio.angrybirds&showAll=1
All this can be seen here: https://developer.amazon.com/sdk/in-app-purchasing/sample-code/deeplink.html
Update(deep linking):
amzn://apps/android?p=
Best way is to look at their website (or here), which currently states this :
search: amzn://apps/android?s=amazon%20mp3 or http://www.amazon.com/gp/mas/dl/android?s=amazon%20mp3
detail page using package name: amzn://apps/android?p=com.amazon.mp3 or http://www.amazon.com/gp/mas/dl/android?p=com.amazon.mp3
detail page using unique ID ("asin") : amzn://apps/android?asin=B004FRX0MY or http://www.amazon.com/gp/mas/dl/android?asin=B004FRX0MY
show all apps of the developer who made the app: amzn://apps/android?p=com.amazon.mp3&showAll=1 or http://www.amazon.com/gp/mas/dl/android?p=com.amazon.mp3&showAll=1
Amazon supports their own deep links now: https://developer.amazon.com/appsandservices/apis/earn/in-app-purchasing/docs/deeplink
E.g. you can start an intent with uri amzn://apps/android?p=my.package.name.
From - https://developer.amazon.com/help/tuabg.html
For in-app advertising or mobile browser based linking, please:
Use this link structure: http:// www.amazon.com/gp/mas/dl/android?p=com.example.package/ref=mas_pm_app_name
For a link that directs to a list of all of your apps within our U.S. store, please:
Use this link structure: http://www.amazon.com/gp/mas/dl/android?p=com.example.package&showAll=1
Now, you think amazon would have this correct on their own website, but the first part that I put in bold is wrong. This is what it should actually be:
http://www.amazon.com/gp/mas/dl/android?p=com.example.package&ref=mas_pm_app_name
Notice the & instead of the / between the package name and ref. Hopefully this helps some other people since this little detail wasted some of my time...
Here's the solution I came up with using the advice below from chiuki:
I added a boolean to one of my resource files that indicates whether or not the app is published in the Amazon AppStore or Android Market. Yeah, you have to change it whenever you publish your app, but think of it sort of like remembering to set debuggable to "false" when you publish. Put it on a check list. It goes like this:
In resource file:
<bool name="app_is_in_amazon_app_store">true< /bool>
In code:
public class SomeUtil
{
private static Boolean isInAmazonAppStore;
public static boolean isInAmazonAppStore(Activity activity)
{
if (isInAmazonAppStore == null)
{
isInAmazonAppStore = activity.getResources().getBoolean(R.bool.app_is_in_amazon_app_store) ;
}
return isInAmazonAppStore;
}
public static void startOtherMarketAppsActivity(Activity activity)
{
try
{
Intent otherApps = null;
if (isInAmazonAppStore(activity))
{
otherApps = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.amazon.com/gp/mas/dl/android?p=" + getPackageNameInAmazonAppStore(activity) + "&showAll=1"));
}
else
{
otherApps = new Intent(Intent.ACTION_VIEW,Uri.parse("market://search?q=pub:\"" + getAndroidDeveloperName(activity) + "\""));
}
activity.startActivity(otherApps);
}
catch(Exception ex){ /* error handling */}
}

Categories

Resources