Когда я хочу получить доступ к SMS, появляется ошибка «Попытка вызвать виртуальный метод для ссылки на нулевой объект» - PullRequest
0 голосов
/ 08 марта 2019

Я попытался получить SMS, а затем добавил его в базу данных Firebase в реальном времени и изменил баланс конкретной учетной записи, но эта ошибка появляется, когда я хочу изменить баланс:

E / AndroidRuntime: FATAL EXCEPTION: main Процесс: com.example.nouraalqahtani.debrah2, PID: 4500 java.lang.NullPointerException: попытка вызвать виртуальный метод 'java.lang.String java.lang.String.trim ()' для ссылки на пустой объект на солнце.Ошибка.accesssms $ 3.onDataChange (accesssms.java:304) на com.google.firebase.database.core.ValueEventRegistration.fireEvent (com.google.firebase: firebase-database @@ 16.0.6: 75) на com.google.firebase.database.core.view.DataEvent.fire (com.google.firebase: firebase-database @@ 16.0.6: 63) на com.google.firebase.database.core.view.EventRaiser $ 1.run (com.google.firebase: база данных firebase @@ 16.0.6: 55) на android.os.Handler.handleCallback (Handler.java:790) на android.os.Handler.dispatchMessage (Handler.java:99) на android.os.Looper.loop (Looper.java:164) в android.app.ActivityThread.main (ActivityThread.java:6494) в java.lang.reflect.Method.invoke (собственный метод) в com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run (RuntimeInit.java:438) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)

, и этот класс accesssms

package com.example.nouraalqahtani.debrah2;

import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

  import com.google.firebase.database.DataSnapshot;
  import com.google.firebase.database.DatabaseError;
  import com.google.firebase.database.DatabaseReference;
  import com.google.firebase.database.FirebaseDatabase;
  import com.google.firebase.database.ValueEventListener;

   import java.text.SimpleDateFormat;
   import java.util.ArrayList;
   import java.util.Date;
   import java.util.Locale;


public class accesssms extends AppCompatActivity {
private static accesssms inst;
ArrayList<String> smsMessagesList = new ArrayList<String>();
ListView smsListView;
ArrayAdapter arrayAdapter;
DatabaseReference myRef;
String day;
String updatebalance;
String accounting;
String accountnumber;
String smsbody;
int count;
int childrencount;
double balance;
double amount;
int  childrencountinflow;
String type;
String bank;
String amountstr;

public static accesssms instance() {
    return inst;
}
@Override
public void onStart() {
    super.onStart();
    inst = this;
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_accesssms);
    myRef= 
  FirebaseDatabase.getInstance().getReference("user_account").child(" . 
   (username)").child("bank_accounts");
    day = new SimpleDateFormat("yyyy-MM-dd", 
    Locale.getDefault()).format(new Date());
    smsListView = (ListView) findViewById(R.id.SMSList);

    arrayAdapter = new ArrayAdapter<String>(this, 
    android.R.layout.simple_list_item_1, smsMessagesList);
    smsListView.setAdapter(arrayAdapter);


    // Add SMS Read Permision At Runtime
    // Todo : If Permission Is Not GRANTED
    if(ContextCompat.checkSelfPermission(getBaseContext(),"android.permission.READ_SMS") ==PackageManager.PERMISSION_GRANTED) {

        // Todo : If Permission Granted Then Show SMS
        refreshSmsInbox();

    } else {
        // Todo : Then Set Permission
        final int REQUEST_CODE_ASK_PERMISSIONS = 123;
        ActivityCompat.requestPermissions(accesssms.this, new String[] 
        {"android.permission.READ_SMS"}, REQUEST_CODE_ASK_PERMISSIONS);
          }

             }
public void refreshSmsInbox() {
    ContentResolver contentResolver = getContentResolver();
    Cursor smsInboxCursor = contentResolver.query(Uri.parse("content://sms/inbox"), null, null, null, null);
    int indexBody = smsInboxCursor.getColumnIndex("body");
    int indexAddress = smsInboxCursor.getColumnIndex("address");
    if (indexBody < 0 || !smsInboxCursor.moveToFirst()) return;
    arrayAdapter.clear();
    do {
        String str = "SMS From: " + smsInboxCursor.getString(indexAddress) +
                "\n" + smsInboxCursor.getString(indexBody) + "\n";
        arrayAdapter.add(str);


        //if it samba bank
        if (smsInboxCursor.getString(indexAddress).equals(".Samba")) {
            smsbody = smsInboxCursor.getString(indexBody);

            int ende = smsbody.indexOf(' ');
            final String transaction = smsbody.substring(0, ende);
            //to check if it outflow or inflow

            //if it outflow
            if (transaction.equals("دفع")) {

                type = "outflow";


                myRef.addValueEventListener(new ValueEventListener() {
                     @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                         //Take last three number card number
                         int accountnumberstart = smsbody.lastIndexOf(".");
                         count = accountnumberstart +5;
                         accountnumber = smsbody.substring(accountnumberstart+2 , count);

                         for (DataSnapshot ds : dataSnapshot.getChildren()) {
                             String dataaccountOUT = ds.child("account_no").getValue(String.class);

                             if (Integer.parseInt(accountnumber)==Integer.parseInt(dataaccountOUT)) {


                                 childrencount=(int)ds.child("outflow").getChildrenCount();
                                 bank=ds.getKey();
                                 addoutflow();

                             } } }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }}); }



            else if (transaction.equals("تم")) {
                type = "inflow";
                //take account number

                myRef.addValueEventListener(new ValueEventListener() {

                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        //Take the last four numbers of account number
                        int accountnumberstart = smsbody.indexOf("حساب");
                        count = accountnumberstart+15 ;
                        accountnumber = smsbody.substring(accountnumberstart +11, count);
                                for (DataSnapshot ds : dataSnapshot.getChildren()) {
                              String dataaccount = ds.child("fourfirstdigit").getValue(String.class);
                              if (Integer.parseInt(accountnumber)==Integer.parseInt(dataaccount)){
                                childrencountinflow=(int)ds.child("inflow").getChildrenCount();
                                bank=ds.getKey();
                                addinflow();

                        }

                    }}


                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }
                });


            }
        }} while (smsInboxCursor.moveToNext());

    blanacechange();
   }





public void updateList(final String smsMessage) {
    arrayAdapter.insert(smsMessage, 0);
    arrayAdapter.notifyDataSetChanged();
}




public void toastMessage(String message){
    Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}





public void addoutflow(){

   // counter=counter+1;
 //   String co=Integer.toString(counter);
        int accounttotalstart = smsbody.lastIndexOf("بقيمة");
        int accounttotalend = smsbody.lastIndexOf("ريال");
        accounting = smsbody.substring(accounttotalstart + 6, accounttotalend);

        amountstr=arabicToenglish(accounting);
        myRef.child(bank).child("outflow").child("6").child("amount").setValue(amountstr);

        //change the balance



        //take vendor name
        int vendorstart = smsbody.lastIndexOf("*", count + 1);
        int vendorend = smsbody.lastIndexOf(",");

        String vendor = smsbody.substring(vendorstart + 3, vendorend);
        //add vendor name to database
        myRef.child(bank).child("outflow").child("6").child("vendor").setValue(vendor);



        //add current time

        int timstart = smsbody.lastIndexOf(",");
        int timend = smsbody.lastIndexOf("/");
        String date = smsbody.substring(timstart + 1, timend + 4);
        myRef.child(bank).child("outflow").child("6").child("date").setValue(arabicToenglish(date));


        int ti = smsbody.lastIndexOf(" ");
        String time = smsbody.substring(timend + 4, ti);
      //  myRef.child(bank).child("outflow").child("6").child("time").setValue(arabicToenglish(time));
        //to check if it AM OR PM

        String AMorPM = smsbody.substring(ti + 1);

        if (AMorPM.equals("صباحاً")) {
            myRef.child(bank).child("outflow").child("6").child("time").setValue(arabicToenglish(time) + " AM");
        } else
            myRef.child(bank).child("outflow").child("6").child("time").setValue(arabicToenglish(time) + " PM");


    }





public void addinflow(){

        int accounttotalstart = smsbody.lastIndexOf("مبلغ");
        int accounttotalend = smsbody.indexOf(" ");
        accounting = smsbody.substring(accounttotalstart + 4, accounttotalend);
    amountstr=arabicToenglish(accounting);


    myRef.child(bank).child("inflow").child("2").child("amount") 
     .setValue(amountstr);

        //change the balance



        int timstart = smsbody.lastIndexOf("في");
        int timend = smsbody.lastIndexOf("-");
        String date = smsbody.substring(timstart + 2, timend + 5);
        myRef.child(bank).child("inflow").child("2").child("date").setValue(arabicToenglish(date));


        int ti = smsbody.lastIndexOf(" ");
        String time = smsbody.substring(timend + 4, ti);
        myRef.child(bank).child("inflow").child("2").child("time").setValue(arabicToenglish(time));
        //to check if it AM OR PM

        String AMorPM = smsbody.substring(ti + 1);
        if (AMorPM.equals("صباحاً")) {
            myRef.child(bank).child("inflow").child("2").child("time").setValue(time + " AM");
        } else
            myRef.child(bank).child("inflow").child("2").child("time").setValue(time + " PM");


}


private static String arabicToenglish(String number)
{
    char[] chars = new char[number.length()];
    for(int i=0;i<number.length();i++) {
        char ch = number.charAt(i);
        if (ch >= 0x0660 && ch <= 0x0669)
            ch -= 0x0660 - '0';
        else if (ch >= 0x06f0 && ch <= 0x06F9)
            ch -= 0x06f0 - '0';
        chars[i] = ch;
    }
    return new String(chars);
}


public void blanacechange() {


    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
           String databa = dataSnapshot.child(bank).child("balance").getValue(String.class);
            String am = dataSnapshot.child(bank).child("6").child("amount").getValue(String.class);
           balance=Double.parseDouble(databa);
           amount=Double.parseDouble(am);



            if (type.equals("outflow")){
                balance = balance - amount;
            myRef.child(bank).child("balance").setValue(Double.toString(balance));}

            if (type.equals("inflow")){
                balance=balance+amount;
                myRef.child(bank).child("balance").setValue(Double.toString(balance));
            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

}



  }

А это моя база данных

enter image description here

1 Ответ

0 голосов
/ 08 марта 2019

В сообщении об ошибке говорится, что у вас есть:

Попытка вызвать виртуальный метод 'java.lang.String java.lang.String.trim ()' для ссылки на пустой объект

Это означает, что где-то в вашем приложении какой-то код вызывает trim() на null.Поскольку в вашем коде нет вызовов trim, вам нужно следить за трассировкой стека, чтобы увидеть, какой вызов в вашем коде действительно вызывает проблему.

И он говорит вам, что это происходит:

в sun.misc.FloatingDecimal.readJavaFormatString (FloatingDecimal.java:1838)

в sun.misc.FloatingDecimal.parseDouble (FloatingDecimal.java:110)

в java.lang.Double.parseDouble (Double.java:539)

в com.example.nouraalqahtani.debrah2.accesssms $ 3.onDataChange (accesssms.java:304)

Теперь эта последняя строка - первая, которую вы можете распознать.Проблема возникает в строке 304 accesssms.java.Вы можете проверить, какая именно строка находится в вашей IDE, но я упустил тот факт, что вы, очевидно, звоните parseDouble по этой линии.Таким образом, проблема начинается с вызова parseDouble.

Если я посмотрю на код, которым вы поделились, вы наберете parseDouble в следующих двух строках:

      String databa = dataSnapshot.child(bank).child("balance").getValue(String.class);
        String am = dataSnapshot.child(bank).child("6").child("amount").getValue(String.class);
       balance=Double.parseDouble(databa);
       amount=Double.parseDouble(am);

Итак, проблемадолжен прийти из любого из этих рядов.В любом случае кажется вероятным, что вы получаете null обратно от вызова к getValue(String.class), что означает, что либо нет значения в снимке, либо (менее вероятно), что значение не является строкой.

Трудно точно определить, какие данные вы слушаете, но насколько я вижу, вы инициализируете myRef как:

myRef= FirebaseDatabase.getInstance().getReference("user_account").child(" . 
(username)").child("bank_accounts");

Если это так,пожалуйста, сначала проверьте, что . там не вызывает проблемы.

Если это действительно так, у вас есть ссылка на все банковские счета пользователя.Таким образом, если вы добавите ValueEventListener к этой ссылке, ваш onDataChange будет вызван с DataSnapshot всеми банковскими счетами.Чтобы получить доступ к каждому отдельному банковскому счету, вам нужно перебрать дочерние узлы этого снимка.Что-то вроде:

myRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
       for (DataSnapshot accountSnapshot: dataSnapshot.getChildren()) {
           String databa = accountSnapshot.child("balance").getValue(String.class);
            String am = accountSnapshot.child("amount").getValue(String.class);
            balance=Double.parseDouble(databa);
            amount=Double.parseDouble(am);
           ...
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException(); // don't ignore errors
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...