- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的应用程序制作快完成了,但我一直在尝试解决最后一个问题。我做了一个 Activity ,显示使用 FirestoreRecyclerAdapter
从 Firestore 获取的数据,它在我的模拟器上运行时完美运行。但是在我使用 minifyEnabled:true
生成签名的 APK 并将其安装到我的设备上之后,RecyclerView 只显示空白。当我设置 minifyEnabled:false
时,它工作得很好。以下是我的代码
对于 TransactionRecycler 类
public class TransactionRecycler {
private String payment_date;
private String status;
private String meternumber;
public String reference;
private String amount_formatted;
private Double PurchasedUnits;
private Double FreeUnits;
private Double Vat;
public String id;
private String payment_time;
// public String state;
private String token;
public String address;
private String account_name;
public TransactionRecycler(String payment_date, String status, String meternumber, String reference, String id, String amount_formatted, String payment_time, String token, Double PurchasedUnits,
Double FreeUnits, Double Vat, String account_name, String address){
this.payment_date = payment_date;
this.status = status;
this.meternumber = meternumber;
this.reference = reference;
this.amount_formatted = amount_formatted;
this.PurchasedUnits = PurchasedUnits;
this.Vat = Vat;
// this.state = state;
this.FreeUnits = FreeUnits;
this.id = id;
this.payment_time = payment_time;
this.token = token;
this.account_name = account_name;
this.address = address;
}
public TransactionRecycler(){};
public void setDate(String payment_date){this.payment_date = payment_date;}
public void setId(String id){this.id =id;}
// public void setState(String id){this.state =state;}
public String getPayment_date(){return payment_date;}
public String getStatus(){return status;}
public String getMeternumber(){return meternumber;}
public String getReference(){return reference;}
public String getAddress(){return address;}
public String getAmount_formatted(){return amount_formatted;}
public Double getPurchasedUnits(){return PurchasedUnits;}
public Double getFreeUnits(){return FreeUnits;}
public Double getVat(){return Vat;}
public String getId(){return id;}
// public String getstate(){return state;}
public String getPayment_time(){return payment_time;}
public String getToken(){return token;}
public String getAccount_name(){return account_name;}
}
对于 TRAnsactionActivity
public class TransactionActivity extends AppCompatActivity {
private static final String TAG = "TransactionActivity";
private final static String strUrlId= "https://www.eliminateramp.com?exmen=";
private static final int SERVICE_CHARGE = 100;
private static final String PLEASE_CHECK_YOUR_METER_NUMBER_AND_TRY_AGAIN = "Please check your meter number and try again";
private static final String COULDN_T_CONNECT_AT_THIS_TIME_PLEASE_TRY_AGAIN = "Couldn't connect at this time, Please try again";
private static final String FAILLED = "failled";
private static final String NOT_FOUND = "NOT FOUND";
private FirebaseAuth mAuth;
private String userID;
private RecyclerView mTransactionList;
protected LinearLayoutManager linearLayoutManager;
public FirestoreRecyclerAdapter adapter;
private SlidingUpPanelLayout mLayout;
private NavigationView navigation;
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mToggle;
private static final String SPACE = " ";
private static String phone;
private Button charname;
private TextView emailview;
private TextView fullnameview;
private TextView priceidrc;
private static TextView post_meterno;
private static String aamount;
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.top_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transaction);
mTransactionList = findViewById(R.id.friend_listinc);
mLayout = findViewById(R.id.sliding_layout);
mAuth = FirebaseAuth.getInstance();
userID = mAuth.getCurrentUser().getUid();
Log.d("Error","The UID is: "+userID);
Toolbar mToolbar = findViewById(R.id.nav_actionbar);
setSupportActionBar(mToolbar);
mDrawerLayout = findViewById(R.id.drawerlayout);
navigation = findViewById(R.id.navigationview);
mToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.open, R.string.close);
View headerView = navigation.getHeaderView(0);
emailview = headerView.findViewById(R.id.emailviewraw);
fullnameview = headerView.findViewById(R.id.fullnameviewid);
charname = headerView.findViewById(R.id.charnameid);
mDrawerLayout.addDrawerListener(mToggle);
mToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
try{
getUserData();
}catch (Exception e){
Log.d(TAG, "Failed to get user Data at this time coz: "+e);
}
ImageView imgview = findViewById(R.id.closeid);
imgview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLayout.animate();
mLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
}
});
charname.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(TransactionActivity.this,UpdateActivity.class));
}
});
init();
inTrans();
initInstances();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return mToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
}
private void initInstances() {
// getSupportActionBar().setHomeButtonEnabled(true);
// getSupportActionBar().setDisplayHomeAsUpEnabled(true);
navigation = findViewById(R.id.navigationview);
navigation.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
int id = menuItem.getItemId();
switch (id) {
case R.id.nav_home:
//Do some thing here
// add navigation drawer item onclick method here
Intent intent2 = new Intent(TransactionActivity.this, HomePageActivity.class);
startActivity(intent2);
break;
case R.id.nav_estimate:
mDrawerLayout.closeDrawer(GravityCompat.START);
break;
//Do some thing here
// add navigation drawer item onclick method here
case R.id.nav_Settings:
//Do some thing here
// add navigation drawer item onclick method here
Intent intent3 = new Intent(TransactionActivity.this, HelpActivity.class);
startActivity(intent3);
break;
case R.id.nav_hc:
//Do some thing here
// add navigation drawer item onclick method here
Intent intent = new Intent(TransactionActivity.this, HelpCenterActivity.class);
startActivity(intent);
break;
}
return false;
}
});
}
private void init(){
linearLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false);
mTransactionList.setLayoutManager(linearLayoutManager);
}
private void inTrans(){
Query query = FirebaseFirestore.getInstance().collection("user-orders").document(userID).collection("successful-orders").orderBy("RequestedOn");
FirestoreRecyclerOptions<TransactionRecycler> response = new FirestoreRecyclerOptions.Builder<TransactionRecycler>()
.setQuery(query, TransactionRecycler.class)
.build();
adapter = new FirestoreRecyclerAdapter<TransactionRecycler, TransactionRecyclerHolder>(response){
@Override
public TransactionRecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.transaction_list, parent, false);
return new TransactionRecyclerHolder(view);
}
@Override
public void onError(@NonNull FirebaseFirestoreException e) {
Log.e("error", e.getMessage());
}
@Override
protected void onBindViewHolder(@NonNull TransactionRecyclerHolder holder, int position, @NonNull final TransactionRecycler model) {
//progressBar.setVisibility(View.GONE);
holder.setDate(model.getPayment_date());
holder.setStatus(model.getStatus());
holder.setReference(model.getId());
holder.setMeterno(model.getMeternumber());
holder.setPrice(model.getAmount_formatted());
mLayout.setFadeOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLayout.animate();
mLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLayout.setPanelHeight(4);
mLayout.animate();
// mLayout.setAnchorPoint(2.0f);
mLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
priceidrc = findViewById(R.id.priceidsc);
TextView dateidrc = findViewById(R.id.dateidsc);
TextView referenceidrc = findViewById(R.id.refidsc);
TextView statusidrc = findViewById(R.id.statusidsc);
TextView meternoidrc = findViewById(R.id.meternoidsc);
TextView paymenttimeidrc = findViewById(R.id.paymenttimeidsc);
TextView tokenidrc = findViewById(R.id.tokenidsc);
TextView creditidrc = findViewById(R.id.creditidsc);
TextView freeunitsrc = findViewById(R.id.freeunitsidsc);
TextView vatrc = findViewById(R.id.vatidsc);
TextView accountnameidrc = findViewById(R.id.namesidsc);
TextView address = findViewById(R.id.addressidsc);
dateidrc.setText(model.getPayment_date());
statusidrc.setText(model.getStatus());
meternoidrc.setText(model.getMeternumber());
priceidrc.setText(model.getAmount_formatted());
referenceidrc.setText(model.getId());
paymenttimeidrc.setText(model.getPayment_time());
tokenidrc.setText(model.getToken());
creditidrc.setText(String.valueOf(model.getPurchasedUnits()));
freeunitsrc.setText(String.valueOf(model.getFreeUnits()));
vatrc.setText(String.valueOf(model.getVat()));
accountnameidrc.setText(model.getAccount_name());
address.setText(model.getAddress());
}
});
}
};
adapter.notifyDataSetChanged();
mTransactionList.setAdapter(adapter);
}
@Override
public void onStart() {
super.onStart();
adapter.startListening();
}
@Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
public static class TransactionRecyclerHolder extends RecyclerView.ViewHolder {
View mView;
TransactionRecyclerHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDate(String payment_date) {
TextView post_date = mView.findViewById(R.id.dateid);
post_date.setText(payment_date);
}
public void setStatus(String status) {
TextView post_status = mView.findViewById(R.id.statusid);
post_status.setText(status);
}
public void setMeterno(String meterno) {
post_meterno = mView.findViewById(R.id.meternoid);
post_meterno.setText(meterno);
}
public void setReference(String reference) {
TextView post_ref = mView.findViewById(R.id.refid);
post_ref.setText(reference);
}
public void setPrice(String price) {
TextView post_price = mView.findViewById(R.id.priceid);
post_price.setText(price);
aamount=price;
}
}
public void getUserData() {
mAuth= FirebaseAuth.getInstance();
try{
userID = mAuth.getCurrentUser().getUid();
}catch(Exception e){
Log.d(TAG, "Failled somehow");
}
Log.d(TAG, "ur uid => "+userID);
DocumentReference mDocRef = FirebaseFirestore.getInstance().collection("users").document(userID);
mDocRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()){
DocumentSnapshot doc = task.getResult();
String firstname = doc.get("firstName").toString();
String lastname = doc.get("lastName").toString();
phone = doc.get("phone").toString();
String fullname = firstname+SPACE+lastname;
fullnameview.setText(fullname);
try{
emailview.setText(mAuth.getCurrentUser().getEmail());
}catch(Exception e){
Log.d(TAG,"oops");
}
charname.setText(firstname.substring(0,1));
}
}
});
}
public void buyAgain(View view){
final Dialog dialog = new Dialog(TransactionActivity.this);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.setCanceledOnTouchOutside(false);
dialog.setContentView(R.layout.progressbar);
String price = aamount.replaceAll("\\D","");
final int amount = Integer.parseInt(price) + SERVICE_CHARGE;
final String mn = post_meterno.getText().toString();
final String ml = "amstadam";
final String ref = String.valueOf(Calendar.getInstance().getTimeInMillis());
@SuppressLint("StaticFieldLeak") AsyncTask<String, String, String> jesgetnames = new AsyncTask<String, String, String>() {
@Override
protected String doInBackground(String... params) {
String geMtName;
String urlMtName = strUrlId+post_meterno.getText().toString().trim();
Log.d(TAG, "The string:" + urlMtName);
try {
URL url = new URL(urlMtName);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.connect();
BufferedReader bf = new BufferedReader(new InputStreamReader(con.getInputStream()));
String value = bf.readLine();
Log.d(TAG, "Value of value is: " + value);
if(value.equals("not found")){
geMtName = "NOT FOUND";
}else{
JSONObject parentJson = new JSONObject(value);
String meternumber = parentJson.getString("xmen");
String metername = parentJson.getString("x_name");
String address = parentJson.getString("address");
geMtName = metername+"/"+meternumber+"/"+address;
}
Log.d(TAG, "meter name after get is: " + geMtName);
} catch (Exception e) {
// Log.d(TAG, "Faiiled coz: "+ e);
geMtName = "failled";
e.printStackTrace();
}
Log.d(TAG, "I dont know if this works " + geMtName);
return geMtName;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d(TAG, "pnPostExecute value: " + s);
String nameSubString;
String numberSubString;
String addressSubString;
// date and time creation
String stringDate = String.valueOf(DateFormat.getDateTimeInstance());
Date stringTime = Calendar.getInstance().getTime();
SimpleDateFormat curFormater = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);
SimpleDateFormat timeFormat = new SimpleDateFormat("h:mm a", Locale.ENGLISH);
Date dateObj = new Date();
Date timeObj = new Date();
try {
dateObj = curFormater.parse(stringDate);
timeObj = timeFormat.parse(String.valueOf(stringTime));
} catch (ParseException e) {
e.printStackTrace();
}
SimpleDateFormat postFormater = new SimpleDateFormat("d MMMM yyyy", Locale.ENGLISH);
SimpleDateFormat postTimeFormater = new SimpleDateFormat("h:mm a", Locale.ENGLISH);
String newDateStr = postFormater.format(dateObj);
String newtimeStr = postTimeFormater.format(timeObj);
switch (s) {
case FAILLED:
nameSubString = FAILLED;
numberSubString = FAILLED;
addressSubString = FAILLED;
break;
case NOT_FOUND:
nameSubString = FAILLED;
numberSubString = FAILLED;
addressSubString = FAILLED;
break;
default:
String[] split = s.split("/");
nameSubString = split[0];
numberSubString = split[1];
addressSubString = split[2];
break;
}
switch (s) {
//TODO: Change toast message to reflect Json in future
case FAILLED:
//TODO: after creating layout, go back to previous layout and display toast message
Toast.makeText(TransactionActivity.this, COULDN_T_CONNECT_AT_THIS_TIME_PLEASE_TRY_AGAIN, Toast.LENGTH_SHORT).show();
dialog.dismiss();
break;
case NOT_FOUND:
Toast.makeText(TransactionActivity.this, PLEASE_CHECK_YOUR_METER_NUMBER_AND_TRY_AGAIN, Toast.LENGTH_SHORT).show();
dialog.dismiss();
break;
default:
Intent meterIntent = new Intent(TransactionActivity.this, MeterNumActivity.class);
meterIntent.putExtra("meternum", mn);
meterIntent.putExtra("meterprice", amount);
meterIntent.putExtra("meterlocation", ml);
meterIntent.putExtra("reference", ref);
meterIntent.putExtra("meteracctname", nameSubString);
meterIntent.putExtra("meteracctnumber", numberSubString);
meterIntent.putExtra("meteracctaddress", addressSubString);
meterIntent.putExtra("uuid", userID);
meterIntent.putExtra("date_created", newDateStr);
meterIntent.putExtra("time_created", newtimeStr);
meterIntent.putExtra("phone", phone);
meterIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(meterIntent);
break;
}
}
};
dialog.show();
jesgetnames.execute();
}
@Override
public void onBackPressed() {
Intent i= new Intent(this,HomePageActivity.class);
startActivity(i);
finish();
}
}
我的 Gradle 是
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.menofx.xmen"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:cardview-v7:26.1.0'
implementation 'com.firebaseui:firebase-ui-firestore:3.1.3'
implementation 'com.firebaseui:firebase-ui-auth:3.1.3'
implementation 'com.firebaseui:firebase-ui-database:3.1.3'
implementation "com.google.firebase:firebase-firestore:11.8.0"
implementation "com.android.support:recyclerview-v7:26.1.0"
implementation "com.google.android.gms:play-services-auth:11.8.0"
implementation 'co.paystack.android:paystack:3.0.9'
implementation 'br.com.simplepass:loading-button-android:1.8.4'
implementation 'com.github.faruktoptas:FancyShowCaseView:1.0.0'
implementation 'com.sothree.slidinguppanel:library:3.4.0'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:support-vector-drawable:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:0.5'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
implementation project(':library')
}
apply plugin: 'com.google.gms.google-services'
如果需要,我的 proguard 规则是空的。这是我第一次使用 firebase UI,所以我什至不知道如何诊断问题。感谢您的帮助。
最佳答案
您需要将您的 POJO(模型类)放在一个包中并将该包添加到您的混淆器规则中,或者您可以添加这些类所在的所有包(我个人只是为它们使用一个包)。 Firebase 在序列化和反序列化过程中使用反射,因此它不能使用混淆的类名。一旦你将它们全部放在一个包中,将此规则添加到你的混淆文件中以防止混淆:
-keep class package.to.pojos.** { *; }
如果您希望将它们保留在原处,只需使用 -keep class
关键字为每个模型类添加一条规则,后跟类的完整路径(按包方式)。
关于java - 生成带有 minifyEnabled 设置为 true 的签名 APK 后,firebase UI 输出空白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50109627/
我正在尝试使用以下 keytool 命令为我的应用程序生成 keystore : keytool -genkey -alias tomcat -keystore tomcat.keystore -ke
编辑:在西里尔正确解决问题后,我注意到只需将生成轴的函数放在用于生成标签的函数下面就可以解决问题。 我几乎读完了 O'Reilly 书中关于 D3.js 的教程,并在倒数第二页上制作了散点图,但是当添
虽然使用 GraphiQL 效果很好,但我的老板要求我实现一个用户界面,用户可以在其中通过 UI 元素(例如复选框、映射关系)检查呈现给他们的元素并获取数据,这样做将为该人生成 graphql 输入,
我尝试在 Netbean 6.8 中使用 ws-import 生成 Java 类。我想重新生成 jax-ws,因为在 ebay.api.paypalapi 包中发现了一个错误(我认为该错误是由于 Pa
我有一个 perl 脚本,它获取系统日期并将该日期写入文件名。 系统日期被分配给 TRH1 变量,然后它被设置为一个文件名。 $TRH1 =`date + %Y%m%d%H%M`; print "TR
我是 Haskell 的新手,需要帮助。我正在尝试构建一种必须具有某种唯一性的新数据类型,因此我决定使用 UUID 作为唯一标识符: data MyType = MyType { uuid ::
我制作了一个脚本,它可以根据 Mysql 数据库中的一些表生成 XML。 该脚本在 PHP 中运行。 public function getRawMaterials($apiKey, $format
所以这是我的项目中的一个问题。 In this task, we will use OpenSSL to generate digital signatures. Please prepare a f
我在 SAS LIFEREG 中有一个加速故障时间模型,我想绘制它。因为 SAS 在绘图方面非常糟糕,我想实际重新生成 R 中曲线的数据并将它们绘制在那里。 SAS 提出了一个尺度(在指数分布固定为
我正在为 Django 后端制作一个样板,并且我需要能够使它到达下一个下载它的人显然无法访问我的 secret key 的地方,或者拥有不同的 key 。我一直在研究一些选项,并在这个过程中进行了实验
我正在创建一个生成采购订单的应用程序。我可以根据用户输入的详细信息创建文本文件。我想生成一个看起来比普通文本文件好得多的 Excel。有没有可以在我的应用程序中使用的开源库? 最佳答案 目前还没有任何
我正在尝试使用 ScalaCheck 为 BST 创建一个 Gen,但是当我调用 .sample 方法时,它给了我 java.lang.NullPointerException。我哪里错了? seal
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我尝试编写一些代码,例如(在verilog中): parameter N = 128; if (encoder_in[0] == 1) begin 23 binary_out = 1;
我正忙于在 Grails 项目中进行从 MySQL 到 Postgres 的相当复杂的数据迁移。 我正在使用 GORM 在 PostGres 中生成模式,然后执行 MySQL -> mysqldump
如何使用纯 XSLT 生成 UUID?基本上是寻找一种使用 XSLT 创建独特序列的方法。该序列可以是任意长度。 我正在使用 XSLT 2.0。 最佳答案 这是一个good example 。基本上,
我尝试安装.app文件,但是当我安装并单击“同步”(在iTunes中)时,我开始在设备上开始安装,然后停止,这是一个问题,我不知道在哪里,但我看到了我无法解决的奇怪的事情: 最佳答案 似乎您没有在Xc
自从我生成 JavaDocs 以来已经有一段时间了,我确信这些选项在过去 10 年左右的时间里已经得到了改进。 我能否得到一些有关生成器的建议,该生成器将输出类似于 .Net 文档结构的 JavaDo
我想学习如何生成 PDF,我不想使用任何第三方工具,我想自己用代码创建它。到目前为止,我所看到的唯一示例是我通过在第 3 方 dll 上打开反射器查看的代码,以查看发生了什么。不幸的是,到目前为止我看
我正在从 Epplus 库生成 excel 条形图。 这是我成功生成的。 我的 table 是这样的 Mumbai Delhi Financial D
我是一名优秀的程序员,十分优秀!