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.
Related
Let me quickly describe my setup and goal. I have a android tablet display running Android version 7.1.2
I have a motor controller that is hooked up to the Android tablet via ethernet. In my Android app that controls the motor controller, I use Wifi to communicate with some servers that provide/store data. Currently, I can use an Android simulator (in Android Studio) that allows me to communicate with the motor controller while also using the wifi for calls to the server. When I run the app on the Android tablet itself, I can only have Wifi OR Ethernet active at one time.
According to this post this is a hard limitation in Android itself. It also details some possible fixes, but its quite old and to be honest I do not have any experience in the required steps described by their vague instructions.
Can anyone provide a more up-to-date solution to this problem, preferably one that is a little more detailed for newbies like me? Even just a pointer to learning how to do the necessary steps for fixing this would be great, I've been stuck on this for awhile! Thanks for any help!
EDIT: Here's some relevant info in regards to AlwaysLearning's answer...
The class I use to manage reading from Modbus
public class ModbusRead {
private static final String TAG = "MODBUS READ";
ModbusClient mClientReadAll;
public ModbusRead()
{
// IP = "192.168.124.2";
// port = 502;
mClientReadAll = new ModbusClient(Modbus.IP, Integer.valueOf(Modbus.port));
mClientReadAll.setUnitIdentifier((byte)255);
}
public Runnable readAll()
{
return () -> {
ReadAllFromModbus mReadAll = new ReadAllFromModbus();
mReadAll.execute();
};
}
public class ReadAllFromModbus extends AsyncTask<String, Void, String> {
private final String TAG = "READ ALL FROM MODBUS";
#Override
protected String doInBackground(String... params) {
try
{
mClientReadAll.Connect();
// get all registers
int[] registerBlock = mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_MODE.getRegister()- 1, 16);
int[] wideRegisters = new int[] {
Modbus.convertWideRegister(mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_ACTUAL_POSITION.getRegister() - 1, 2)),
Modbus.convertWideRegister(mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_TARGET_POSITION.getRegister() - 1, 2)),
Modbus.convertWideRegister(mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_ROM_DELTA.getRegister() - 1, 2)),
Modbus.convertWideRegister(mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_REWIND_ZERO.getRegister() - 1, 2))
};
int[] tensionRegister = mClientReadAll.ReadHoldingRegisters(Constants.RegisterRead.HR_ACTUAL_TENSION.getRegister() - 1, 1);
Modbus.updateAllRegisters(registerBlock, wideRegisters, tensionRegister);
}
catch (Exception e)
{
Log.i(TAG, "ERROR IN GETTING ALL REGISTERS LOOP: " + e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try
{
mClientReadAll.Disconnect();
}
catch(Exception e)
{
Log.i(TAG, "ERROR IN DISCONNECTING");
}
}
}
}
The relevant part of my Dashboard class that would handle starting the thread that does all the modbus reading
How would I go about forcing the ModbusRead class to use the Ethernet here?
ModbusRead modbusRead = new ModbusRead();
final ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkRequest requestEthernet = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.build();
final ConnectivityManager.NetworkCallback cbEthernet = new ConnectivityManager.NetworkCallback() {
#Override
public void onAvailable(Network network) {
// connectivityManager.bindProcessToNetwork(network);
try
{
// Modbus.IP = "192.168.124.2"
// Modbus.port = 502
Log.i(TAG, "TRYING TO BIND SOCKET...");
InetAddress address = InetAddress.getByName(Modbus.IP);
Log.i(TAG, "ADDRESS: " + address.toString());
Socket socket = new Socket(address, Modbus.port);
Log.i(TAG, "SOCKET CREATED..." + socket.getInetAddress());
network.bindSocket(socket);
Log.i(TAG, "BOUND ETHERNET");
}
catch (Exception e)
{
e.printStackTrace();
Log.i(TAG, "EXCEPTION: " + e.getMessage());
}
}
};
connectivityManager.requestNetwork(requestEthernet, cbEthernet);
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(modbusRead.readAll(), 2000, 250, TimeUnit.MILLISECONDS);
I'm creating a management that finds impressions, clicks, and leads for Facebook campaigns associated with my business account.
For impressions and clicks, there were no problems but I can not find the leads.
This is the code (taken from Facebook Developer) of the function that tries to calculate the lead of each ad linked to the Facebook campaign.
The values printed by the System Out are:
SIZE: 0,
LIST: []
public void getTotalLeads(Campaign campaignFB) throws APIException {
APINodeList<Ad> ads = campaignFB.getAds().execute();
for (Ad ad : ads) {
Ad adFb = new Ad(ad.getId(), context);
APINodeList<Lead> listLeads = adFb.getLeads().execute();
System.out.println("SIZE: " + listLeads.size());
System.out.println("LIST: " + listLeads);
}
}
in my case the ads were of the form type:
try {
final AdAccount account = new AdAccount(ACCOUNT_ID, context);
final APINodeList<LeadgenForm> forms = account.getLeadGenForms().execute();
for (final LeadgenForm leadgenForm : forms) {
System.out.println(leadgenForm.getId());
final APINodeList<Lead> leads = leadgenForm.getLeads().execute();
for (final Lead lead : leads) {
System.out.println(lead.getFieldFieldData());
}
}
}
catch (final APIException e) {
e.printStackTrace();
}
I am attempting to communicate with a Pi header using Android Things Developer Preview 5. Below is the class I have created to communicate with the header as per the official Android Things documentation:
public class UartComm {
private static final String UART_DEVICE_NAME = "UART1";
private UartDevice mDevice;
private void configureUartFrame(UartDevice uart) throws IOException {
// Configure the UART port
uart.setBaudrate(115200);
}
public void onCreate() {
try {
PeripheralManagerService manager = new PeripheralManagerService();
List<String> deviceList = manager.getUartDeviceList();
if (deviceList.isEmpty()) {
Log.i(TAG, "No UART port available on this device.");
} else {
Log.i(TAG, "List of available devices: " + deviceList);
}
mDevice = manager.openUartDevice(UART_DEVICE_NAME);
configureUartFrame(mDevice);
mDevice.registerUartDeviceCallback(mUartCallback);
} catch (Exception e) {
Log.w(TAG, "Unable to access UART device", e);
}
}
public void readUartBuffer(UartDevice uart) throws IOException {
// Maximum amount of data to read at one time
final int maxCount = 40;
byte[] buffer = new byte[maxCount];
uart.read(buffer, maxCount);
String data = new String(buffer, "UTF-8");
Log.d(TAG, data);
}
private UartDeviceCallback mUartCallback = new UartDeviceCallback() {
#Override
public boolean onUartDeviceDataAvailable(UartDevice uart) {
// Read available data from the UART device
try {
readUartBuffer(uart);
} catch (IOException e) {
Log.w(TAG, "Unable to access UART device", e);
}
// Continue listening for more interrupts
return true;
}
#Override
public void onUartDeviceError(UartDevice uart, int error) {
Log.w(TAG, uart + ": Error event " + error);
}
};
}
In my MainActivity I create an instance of UartComm by doing UartComm device = new UartComm() and the proceed to call device.onCreate()
I have also modified /boot/cmdline.txt and removed the console=serial0,115200 and replaced it with console=tty0, I have also tried just removing the console line without adding console=tty0. In /boot/config.txt I have also removed enable_uart=1 and core-freq=400 and also added dtoverlay=pi3-miniuart-bt I have also tried to remove Bluetooth support altogether by doing dtoverlay=pi3-disable-bt to no avail.
I have tested that the header works and is configured correctly in Rapsbian, where I swapped /dev/ttyAMA0 and /dev/ttyS0 and it worked correctly. I was able to run the screen command on Raspbian with a default baud rate of 115200 and was able to get the desired information.
I would like to do the same in Android Things Developer Preview 5 and have the Bluetooth run over the mini-uart ttyS0 and the header run over ttyAMA0. My desired result is for the header to be accessible over UART0.
An older USB serial device that has the same functionality works, but I would prefer the UART device be physically on top of the Pi, so that is not an option.
Might be wrong but shouldn't:
private static final String UART_DEVICE_NAME = "UART1";
be UART0 i.e.
private static final String UART_DEVICE_NAME = "UART0";
I did a UART example here https://github.com/blundell/androidthings-uart/blob/master/app/src/main/java/com/blundell/tut/MainActivity.java (obviously different hardware) But it's connected to raspberry pi pins in the same way like so:
I know this question has been asked multiple times, but nobody has been able to come up with a working answer from what I have seen.
Im working on an app to intercept text messages and depending on the sending #, pop up with a custom alert. I have it working beautifully with a broadcast receiver, however if the user has goSms installed the onReceive() method is never called as goSms aborts it before it ever reaches my app.
To get around this, Im trying a content observer on content://sms/
Its working just fine, however the onChange() is called twice, with exactly the same parameters. Ive tried to check the time stamps, but they are the same, as is the type and every other parameter I have set.
From what I've seen, this is a common issue, but not one that I've seen answered anywhere.
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
querySMS();
}
protected void querySMS() {
Cursor cur = getContentResolver().query(u, null, null, null, null);
cur.moveToNext(); // this will make it point to the first record, which is the last SMS sent
String type = cur.getString(cur.getColumnIndex("type"));
String body = cur.getString(cur.getColumnIndex("body")); //content of sms
String add = cur.getString(cur.getColumnIndex("address")); //phone num
if (type.equals("1")) {
if (add.equals(Test.SENDER)) {
String[] bodys = body.split(" ", 7);
if (bodys[0].equals("test")) {
test = true;
}
cat = bodys[1];
level = bodys[2];
urgency = bodys[3];
certainty = bodys[4];
carrier = bodys[5];
message = bodys[6];
final Intent intent = new Intent(context, AlertActivity.class);
Bundle b = new Bundle();
b.putString("title", cat);
b.putString("certainty", certainty);
b.putString("urgency", urgency);
b.putString("level", level);
b.putString("message", message);
b.putBoolean("test", test);
intent.putExtras(b);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
carrierName = manager.getNetworkOperatorName();
if (carrierName.replaceAll(" ", "").equals(carrier)) {
context.startActivity(intent);
} else {
//testing
Toast.makeText(context, carrierName.replaceAll(" ", ""), Toast.LENGTH_LONG).show();
}
}
}
}
Because of the onChange() being fired twice, Im getting two alerts as well. I cannot for the life of me figure out a way around this.
If the two are identical:
store each message recv'd
compare it to previous messages recv'd
if not found, process
if found, discard the message
The life of the messages stored should be infinitesimal, a little circular buffer of 5 messages should be fine.
here is my code, it works fine for me
public class SmsObserver extends ContentObserver {
private Context context;
private static int initialPos;
private static final String TAG = "SMSContentObserver";
private static final Uri uriSMS = Uri.parse("content://sms/sent");
public SmsObserver(Handler handler, Context ctx) {
super(handler);
context = ctx;
initialPos = getLastMsgId();
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
queryLastSentSMS();
}
public int getLastMsgId() {
Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null);
cur.moveToFirst();
int lastMsgId = cur.getInt(cur.getColumnIndex("_id"));
Log.i(TAG, "Last sent message id: " + String.valueOf(lastMsgId));
return lastMsgId;
}
protected void queryLastSentSMS() {
new Thread(new Runnable() {
#Override
public void run() {
Cursor cur =
context.getContentResolver().query(uriSMS, null, null, null, null);
if (cur.moveToNext()) {
try {
if (initialPos != getLastMsgId()) {
// Here you get the last sms. Do what you want.
String receiver = cur.getString(cur.getColumnIndex("address"));
System.out.println(" Receiver Ph no :"+receiver);
// Then, set initialPos to the current position.
initialPos = getLastMsgId();
}
} catch (Exception e) {
// Treat exception here
}
}
cur.close();
}
}).start();
}
}//End of class SmsObserver
You can save last message's id and compare it to the id of the message that is returned by cur in onChange. you then can simply disregard the message if ids are the same.
// might contain mistakes, but you'll get the idea:
protected void querySMS() {
Cursor cur = getContentResolver().query(u, null, null, null, null);
cur.moveToNext();
if (lastId == cur.getLong(cur.getColumnIndex("_id")))
return;
lastId = cur.getLong(cur.getColumnIndex("_id"));
... //continue as it was
}
However - GO SMS only prevents other app's from recieving Broadcast if the user selected this option (Recieve Settings - Disable other message notification) - so if the user does not want other apps to disturb him - I think it's good idea not to do so.
I just use SharedPreference to remark last SMS info (like: id\type ...). if it is the same, I will return.
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());