package com.hope.carwallpapers.extra;
import java.lang.reflect.Field;
/**
* Created by croma on 21-08-2016.
*/
public class StringLensFlare {
public final static String O_1 = "{\"I\":\"p(1)\",\"ow\":768,\"oh\":491,\"data\":[{\"image\":\"two\",\"fw\":389,\"fh\":235,\"fx\":162,\"fy\":187},{\"image\":\"one\",\"fw\":389,\"fh\":235,\"fx\":461,\"fy\":187}]}";
public final static String O_2 = "{\"I\":\"p(2)\",\"ow\":768,\"oh\":512,\"data\":[{\"image\":\"two\",\"fw\":757,\"fh\":450,\"fx\":11,\"fy\":0},{\"image\":\"two\",\"fw\":381,\"fh\":227,\"fx\":0,\"fy\":99}]}";
public static String getDeclare(int i) {
try {
StringLensFlare stringLensFlare = new StringLensFlare();
Field f = stringLensFlare.getClass().getDeclaredField("O_" + i);
f.setAccessible(true);
return f.get(stringLensFlare).toString();
} catch (Exception e) {
}
return "";
}
};;
this is my public static filed remove after proguard i have already added in
proguard.txt file as-keepclasseswithmembernames class * {
native <methods>;
}
You are accessing a public static field via reflection, thus you have to instruct ProGuard to keep it:
-keep class StringLensFlare {
static java.lang.String O_*;
}
The other rule that you mention is pretty much useless for this case and completely unrelated.
Related
I created a library project which I built as an AAR file and later included in another project. It's in the libs folder, and the main gradle.build file includes it: implementation fileTree(include: ['*.jar','*.aar'], dir: 'libs')
When I try to use classes of this aar file, all of them are available except one class. I initially imagined it could be Proguard, but I even removed Proguard and it is still not available. It's a public class, and it's even there when I decompile the AAR file.
This is the content:
package com.onboarding;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.Keep;
/**
*
*/
#Keep
public class Builder {
/**
*
*/
public static String mainColor = null;
public static String baseUrl = null;
public static Class firstActivity = null;
public static Class onboardingSettingsActivity = null;
/**
*
*/
public static String tosUrl = null;
public static String privacyUrl = null;
public static String cookieUrl = null;
public static String contactsLearnMoreUrl = null;
/**
*
*/
private static Builder builder = null;
/**
*
*/
private Builder() {}
/**
*
*/
public static Builder init() {
if (builder == null) {
builder = new Builder();
}
return builder;
}
/**
*
*/
public void start(final Context context) {
final Intent intent = new Intent(context, Onboarding1.class);
context.startActivity(intent);
}
/**
*
*/
public Builder setMainColor(final String color) {
mainColor = color;
return this;
}
/**
*
*/
public Builder setBaseUrl(final String url) {
baseUrl = url;
return this;
}
/**
*
*/
public Builder setFirstActivity(final Class c) {
firstActivity = c;
return this;
}
/**
*
*/
public Builder setOnboardingSettingsActivity(final Class c) {
onboardingSettingsActivity = c;
return this;
}
/**
*
*/
public Builder setTosUrl(final String u) {
tosUrl = u;
return this;
}
/**
*
*/
public Builder setPrivacyUrl(final String u) {
privacyUrl = u;
return this;
}
/**
*
*/
public Builder setCookieUrl(final String u) {
cookieUrl = u;
return this;
}
/**
*
*/
public Builder setContactsLearnMoreUrl(final String u) {
contactsLearnMoreUrl = u;
return this;
}
}
Any idea why I can't access this class from the main project?
Thanks!
After randomly working then not working, it appears that a File -> Invalidate caches / restart in Android Studio did the trick.
So apparently Android Studio caches some part of the aar, which even a Clean nor Rebuild would fix.
Hi did you check your dependencies? if it was added in there? what i meant is this one Also refer to this documentation for the difference between implementation and api.
I am generating protobuf class using Squareup Wire protobuf libary
here is my proto file
syntax = "proto2";
package squareup.dinosaurs;
option java_package = "com.squareup.dinosaurs";
message Dinosaur {
// Common name of this dinosaur, like "Stegosaurus".
optional string name = 1;
// URLs with images of this dinosaur.
repeated string picture_urls = 2;
}
and here is my auto generated code
// Code generated by Wire protocol buffer compiler, do not edit.
// Source file: dinosaur/dinosaur.proto at 8:1
package com.squareup.dinosaurs;
import com.squareup.wire.FieldEncoding;
import com.squareup.wire.Message;
import com.squareup.wire.ProtoAdapter;
import com.squareup.wire.ProtoReader;
import com.squareup.wire.ProtoWriter;
import java.io.IOException;
import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.lang.StringBuilder;
import java.util.List;
import okio.ByteString;
public final class Dinosaur extends Message<Dinosaur, Dinosaur.Builder> {
public static final ProtoAdapter<Dinosaur> ADAPTER = new ProtoAdapter<Dinosaur>(FieldEncoding.LENGTH_DELIMITED, Dinosaur.class) {
#Override
public int encodedSize(Dinosaur value) {
return (value.name != null ? ProtoAdapter.STRING.encodedSizeWithTag(1, value.name) : 0)
+ ProtoAdapter.STRING.asRepeated().encodedSizeWithTag(2, value.picture_urls)
+ value.unknownFields().size();
}
#Override
public void encode(ProtoWriter writer, Dinosaur value) throws IOException {
if (value.name != null) ProtoAdapter.STRING.encodeWithTag(writer, 1, value.name);
if (value.picture_urls != null) ProtoAdapter.STRING.asRepeated().encodeWithTag(writer, 2, value.picture_urls);
writer.writeBytes(value.unknownFields());
}
#Override
public Dinosaur decode(ProtoReader reader) throws IOException {
Builder builder = new Builder();
long token = reader.beginMessage();
for (int tag; (tag = reader.nextTag()) != -1;) {
switch (tag) {
case 1: builder.name(ProtoAdapter.STRING.decode(reader)); break;
case 2: builder.picture_urls.add(ProtoAdapter.STRING.decode(reader)); break;
default: {
FieldEncoding fieldEncoding = reader.peekFieldEncoding();
Object value = fieldEncoding.rawProtoAdapter().decode(reader);
builder.addUnknownField(tag, fieldEncoding, value);
}
}
}
reader.endMessage(token);
return builder.build();
}
#Override
public Dinosaur redact(Dinosaur value) {
Builder builder = value.newBuilder();
builder.clearUnknownFields();
return builder.build();
}
};
private static final long serialVersionUID = 0L;
public static final String DEFAULT_NAME = "";
/**
* Common name of this dinosaur, like "Stegosaurus".
*/
public final String name;
/**
* URLs with images of this dinosaur.
*/
public final List<String> picture_urls;
public Dinosaur(String name, List<String> picture_urls) {
this(name, picture_urls, ByteString.EMPTY);
}
public Dinosaur(String name, List<String> picture_urls, ByteString unknownFields) {
super(unknownFields);
this.name = name;
this.picture_urls = immutableCopyOf("picture_urls", picture_urls);
}
#Override
public Builder newBuilder() {
Builder builder = new Builder();
builder.name = name;
builder.picture_urls = copyOf("picture_urls", picture_urls);
builder.addUnknownFields(unknownFields());
return builder;
}
#Override
public boolean equals(Object other) {
if (other == this) return true;
if (!(other instanceof Dinosaur)) return false;
Dinosaur o = (Dinosaur) other;
return equals(unknownFields(), o.unknownFields())
&& equals(name, o.name)
&& equals(picture_urls, o.picture_urls);
}
#Override
public int hashCode() {
int result = super.hashCode;
if (result == 0) {
result = unknownFields().hashCode();
result = result * 37 + (name != null ? name.hashCode() : 0);
result = result * 37 + (picture_urls != null ? picture_urls.hashCode() : 1);
super.hashCode = result;
}
return result;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
if (name != null) builder.append(", name=").append(name);
if (picture_urls != null) builder.append(", picture_urls=").append(picture_urls);
return builder.replace(0, 2, "Dinosaur{").append('}').toString();
}
public static final class Builder extends com.squareup.wire.Message.Builder<Dinosaur, Builder> {
public String name;
public List<String> picture_urls;
public Builder() {
picture_urls = newMutableList();
}
/**
* Common name of this dinosaur, like "Stegosaurus".
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* URLs with images of this dinosaur.
*/
public Builder picture_urls(List<String> picture_urls) {
checkElementsNotNull(picture_urls);
this.picture_urls = picture_urls;
return this;
}
#Override
public Dinosaur build() {
return new Dinosaur(name, picture_urls, buildUnknownFields());
}
}
}
now the issue is i want to directly store the value of Dinosaur into the database using Realm in android. i want Dinosaur class to act as a model.
but the problem is Dinosaur class is declared as final so i cant even derive it.
So is there any design pattern or way that exists to reuse or convert Dinosaur class into model?
You cannot use the Wire Dinosaur with Realm as Wire also require you to extend the Message class, while Realm require you to extend RealmObject.
If you want to combine the two you can create a RealmDinosaur class that accept the wire Dinosaur. Something like this:
public class RealmDinosaur extends RealmObject {
private String name;
private RealmList<RealmString> pictureUrls;
public RealmDinosaur(Dinosaur dino) {
// Fill Realm fields. Note that Realm doesn't support Lists
// with primitive strings yet.
// See https://realm.io/docs/java/latest/#primitive-lists
}
// getter and setters
}
realm.beginTransaction();
realm.copyToRealm(new RealmDinosaur(wireDinosaur));
realm.commitTransaction();
Short answer: no.
For me, this is one of several show-stoppers for wide adoption of Realm.
The developers of Realm don't seem to have considered real-world use-cases such as yours, where your data objects already inherit from something.
They also seem don't seem to get Android's threading requirements.
If you really want to use Realm, I think that you'll have to create another set of objects, likely in another package, that you only use with Realm. Then, you'd have to copy your data from your 'real' objects into the Realm objects.
Personally, for anything non-trivial, I'd either use the built-in SQLite, or find another database that better meets your needs.
Do custom persisters work on Android? I was trying to write one for an entity, and was having no luck in having it run when the entity gets written by the DAO. So, I tried to use the "MyDatePersister" from the examples and I am not able to get that working either.
The persister is nearly identical to the example one -> https://github.com/j256/ormlite-jdbc/blob/master/src/test/java/com/j256/ormlite/examples/datapersister/MyDatePersister.java
In my entity, I have
#DatabaseTable
public class ClickCount implements Serializable {
// other declarations
#DatabaseField(columnName = DATE_FIELD_NAME, persisterClass = MyDatePersister.class)
private Date lastClickDate;
// more code
}
Here is a link to the whole project in Bitbucket -> https://bitbucket.org/adstro/android-sandbox. It's basically one of the ORMLite Android examples with the custom persister example added.
Any feedback would be greatly appreciated.
Thanks
First off, what is the error result you're getting?
I got my custom persister to work just fine, though I didn't try to extend the DateType. Below is a JSONArrayPersister I found the need for. The confusing part is in the naming of the methods, but once they're setup properly, it should be ok.
package com.example.acme.persister;
import com.j256.ormlite.field.FieldType;
import com.j256.ormlite.field.SqlType;
import com.j256.ormlite.field.types.BaseDataType;
import com.j256.ormlite.support.DatabaseResults;
import org.json.JSONArray;
import org.json.JSONException;
import java.sql.SQLException;
public class JSONArrayPersister extends BaseDataType {
public static int DEFAULT_WIDTH = 1024;
private static final JSONArrayPersister singleTon = new JSONArrayPersister();
public static JSONArrayPersister getSingleton() {
return singleTon;
}
private JSONArrayPersister() {
super(SqlType.STRING, new Class<?>[] { String.class });
}
protected JSONArrayPersister(SqlType sqlType, Class<?>[] classes) {
super(sqlType, classes);
}
#Override
public Object parseDefaultString(FieldType fieldType, String defaultStr) {
try {
return new JSONArray(defaultStr);
} catch (JSONException ex)
{
return new JSONArray();
}
}
#Override
public Object resultToSqlArg(FieldType fieldType, DatabaseResults results, int columnPos) throws SQLException {
try {
return new JSONArray( results.getString(columnPos) );
} catch (JSONException ex)
{
return new JSONArray();
}
}
#Override
public Object resultStringToJava(FieldType fieldType, String stringValue, int columnPos) throws SQLException {
return parseDefaultString(fieldType, stringValue);
}
#Override
public int getDefaultWidth() {
return DEFAULT_WIDTH;
}
}
Then in your entity:
#DatabaseField(persisterClass = JSONArrayPersister.class)
private JSONArray something;
I would like to store class object in android sharedpreference. I did some basic search on that and I got some answers like make it serializable object and store it but my need is so simple. I would like to store some user info like name, address, age and boolean value is active. I made one user class for that.
public class User {
private String name;
private String address;
private int age;
private boolean isActive;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean isActive) {
this.isActive = isActive;
}
}
Thanks.
Download gson-1.7.1.jar from this link: GsonLibJar
Add this library to your android project and configure build path.
Add the following class to your package.
package com.abhan.objectinpreference;
import java.lang.reflect.Type;
import android.content.Context;
import android.content.SharedPreferences;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class ComplexPreferences {
private static ComplexPreferences complexPreferences;
private final Context context;
private final SharedPreferences preferences;
private final SharedPreferences.Editor editor;
private static Gson GSON = new Gson();
Type typeOfObject = new TypeToken<Object>(){}
.getType();
private ComplexPreferences(Context context, String namePreferences, int mode) {
this.context = context;
if (namePreferences == null || namePreferences.equals("")) {
namePreferences = "abhan";
}
preferences = context.getSharedPreferences(namePreferences, mode);
editor = preferences.edit();
}
public static ComplexPreferences getComplexPreferences(Context context,
String namePreferences, int mode) {
if (complexPreferences == null) {
complexPreferences = new ComplexPreferences(context,
namePreferences, mode);
}
return complexPreferences;
}
public void putObject(String key, Object object) {
if (object == null) {
throw new IllegalArgumentException("Object is null");
}
if (key.equals("") || key == null) {
throw new IllegalArgumentException("Key is empty or null");
}
editor.putString(key, GSON.toJson(object));
}
public void commit() {
editor.commit();
}
public <T> T getObject(String key, Class<T> a) {
String gson = preferences.getString(key, null);
if (gson == null) {
return null;
}
else {
try {
return GSON.fromJson(gson, a);
}
catch (Exception e) {
throw new IllegalArgumentException("Object stored with key "
+ key + " is instance of other class");
}
}
} }
Create one more class by extending Application class like this
package com.abhan.objectinpreference;
import android.app.Application;
public class ObjectPreference extends Application {
private static final String TAG = "ObjectPreference";
private ComplexPreferences complexPrefenreces = null;
#Override
public void onCreate() {
super.onCreate();
complexPrefenreces = ComplexPreferences.getComplexPreferences(getBaseContext(), "abhan", MODE_PRIVATE);
android.util.Log.i(TAG, "Preference Created.");
}
public ComplexPreferences getComplexPreference() {
if(complexPrefenreces != null) {
return complexPrefenreces;
}
return null;
} }
Add that application class in your manifest's application tag like this.
<application android:name=".ObjectPreference"
android:allowBackup="false"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
....your activities and the rest goes here
</application>
In Your Main Activity where you wanted to store value in Shared Preference do something like this.
package com.abhan.objectinpreference;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
private final String TAG = "MainActivity";
private ObjectPreference objectPreference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
objectPreference = (ObjectPreference) this.getApplication();
User user = new User();
user.setName("abhan");
user.setAddress("Mumbai");
user.setAge(25);
user.setActive(true);
User user1 = new User();
user1.setName("Harry");
user.setAddress("London");
user1.setAge(21);
user1.setActive(false);
ComplexPreferences complexPrefenreces = objectPreference.getComplexPreference();
if(complexPrefenreces != null) {
complexPrefenreces.putObject("user", user);
complexPrefenreces.putObject("user1", user1);
complexPrefenreces.commit();
} else {
android.util.Log.e(TAG, "Preference is null");
}
}
}
In another activity where you wanted to get the value from Preference do something like this.
package com.abhan.objectinpreference;
import android.app.Activity;
import android.os.Bundle;
public class SecondActivity extends Activity {
private final String TAG = "SecondActivity";
private ObjectPreference objectPreference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
objectPreference = (ObjectPreference) this.getApplication();
ComplexPreferences complexPreferences = objectPreference.getComplexPreference();
android.util.Log.i(TAG, "User");
User user = complexPreferences.getObject("user", User.class);
android.util.Log.i(TAG, "Name " + user.getName());
android.util.Log.i(TAG, "Address " + user.getAddress());
android.util.Log.i(TAG, "Age " + user.getAge());
android.util.Log.i(TAG, "isActive " + user.isActive());
android.util.Log.i(TAG, "User1");
User user1 = complexPreferences.getObject("user", User.class);
android.util.Log.i(TAG, "Name " + user1.getName());
android.util.Log.i(TAG, "Address " + user1.getAddress());
android.util.Log.i(TAG, "Age " + user1.getAge());
android.util.Log.i(TAG, "isActive " + user1.isActive());
} }
Hope this can help you. In this answer I used your class for the reference 'User' so you can better understand. However we can not relay on this method if you opted to store very large objects in preference as we all know that we have limited memory size for each app in data directory so that if you are sure you have only limited data to store in shared preference you can use this alternative.
Any suggestions on this implement are most welcome.
the other way is to save each property by itself..Preferences accept only primitive types, so you can't put a complex Object in it
You can use the global class
public class GlobalState extends Application
{
private String testMe;
public String getTestMe() {
return testMe;
}
public void setTestMe(String testMe) {
this.testMe = testMe;
}
}
and then Locate your application tag in nadroid menifest, and add this into it :
android:name="com.package.classname"
and you can set and get the data from any of your activity by using the following code.
GlobalState gs = (GlobalState) getApplication();
gs.setTestMe("Some String");</code>
// Get values
GlobalState gs = (GlobalState) getApplication();
String s = gs.getTestMe();
You could just add some normal SharedPreferences "name", "address", "age" & "isActive" and simply load them when instantiating the class
Simple solution of how to store login value in by SharedPreferences.
You can extend the MainActivity class or other class where you will store the "value of something you want to keep". Put this into writer and reader classes:
public static final String GAME_PREFERENCES_LOGIN = "Login";
Here InputClass is input and OutputClass is output class, respectively.
// This is a storage, put this in a class which you can extend or in both classes:
//(input and output)
public static final String GAME_PREFERENCES_LOGIN = "Login";
// String from the text input (can be from anywhere)
String login = inputLogin.getText().toString();
// then to add a value in InputCalss "SAVE",
SharedPreferences example = getSharedPreferences(GAME_PREFERENCES_LOGIN, 0);
Editor editor = example.edit();
editor.putString("value", login);
editor.commit();
Now you can use it somewhere else, like other class. The following is OutputClass.
SharedPreferences example = getSharedPreferences(GAME_PREFERENCES_LOGIN, 0);
String userString = example.getString("value", "defValue");
// the following will print it out in console
Logger.getLogger("Name of a OutputClass".class.getName()).log(Level.INFO, userString);
I have a problem with AIDL file of android. I downloaded a sample project from internet, I saw in the code, they have an AIDL file. I don't know what this file is and I do some research and write some code.
After create an AIDL file, I declare a method like this
interface IRemoteService{
Map onClick(in int id, in Map state);
}
Then Eclipse will auto generate a file IRemoteService.java and also return error:
cl cannot be resolved to a variable
Did I do something wrong?
Edit
This is IRemoteService.java which auto generated.
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: /home/nampham/Data/works/workspace/MapAidl/src/nampham/mapaidl/IRemoteService.aidl
*/
package nampham.mapaidl;
public interface IRemoteService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements nampham.mapaidl.IRemoteService
{
private static final java.lang.String DESCRIPTOR = "nampham.mapaidl.IRemoteService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an nampham.mapaidl.IRemoteService interface,
* generating a proxy if needed.
*/
public static nampham.mapaidl.IRemoteService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof nampham.mapaidl.IRemoteService))) {
return ((nampham.mapaidl.IRemoteService)iin);
}
return new nampham.mapaidl.IRemoteService.Stub.Proxy(obj);
}
public android.os.IBinder asBinder()
{
return this;
}
#Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_click:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
java.util.Map _arg1;
java.lang.ClassLoader cl = (java.lang.ClassLoader)this.getClass().getClassLoader();
_arg1 = data.readHashMap(cl);
java.util.Map _result = this.click(_arg0, _arg1);
reply.writeNoException();
reply.writeMap(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements nampham.mapaidl.IRemoteService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
public java.util.Map click(int id, java.util.Map state) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.Map _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(id);
_data.writeMap(state);
mRemote.transact(Stub.TRANSACTION_click, _data, _reply, 0);
_reply.readException();
_result = _reply.readHashMap(cl); `<<< This line return error`
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_click = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public java.util.Map click(int id, java.util.Map state) throws android.os.RemoteException;
}
Thanks in advance.
The problem is in:
_result = _reply.readHashMap(cl);
Where cl can't be resolved to a variable because cl is defined locally in onTransact():
java.lang.ClassLoader cl = (java.lang.ClassLoader)this.getClass().getClassLoader();
I don't know if auto-generated code means that it shouldn't be modified or it can't be modified. However, what I can tell you is this error will never go away unless you edited the code and:
Add another cl definition before the error line:
java.lang.ClassLoader cl = (java.lang.ClassLoader)this.getClass().getClassLoader();
_result = _reply.readHashMap(cl);