Mahdi
Mahdi

Reputation: 220

Ussd Exception in Sdk Version 23

I have a ussd code on a button.I add CALL_PHONE permissions in manifest. I use the sdk version (23). This code does not work properly.

Basically what I should do?Thanks.

I have following error:

?E/AndroidRuntime: FATAL EXCEPTION: main Process: com.mahdishekari.mycollectbill, PID: 31738 java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.CALL dat=tel:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx cmp=com.android.server.telecom/.components.UserCallActivity } from ProcessRecord{4e2904f 31738:com.mahdishekari.mycollectbill/u0a109} (pid=31738, uid=10109) with revoked permission android.permission.CALL_PHONE at android.os.Parcel.readException(Parcel.java:1620) at android.os.Parcel.readException(Parcel.java:1573) at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2776) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1509) at android.app.Activity.startActivityForResult(Activity.java:3958) at android.app.Activity.startActivityForResult(Activity.java:3919) at com.mahdishekari.mycollectbill.ActivityMain$C00661.onClick(ActivityMain.java:78) at android.view.View.performClick(View.java:5217) at android.view.View$PerformClick.run(View.java:21349) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5585) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) I/Process: Sending signal. PID: 31738 SIG: 9 Disconnected from the target VM, address: 'localhost:8601', transport: 'socket'

My code:

public class ActivityMain extends ActivityBase {
Button btnLink;
Button btnPayBill;
Button btnRecords;
Button btnScanner;
Button btnSupport;
boolean doubleBackToExitPressedOnce;
DatabaseHelper2 myDbHelper;
TextView tvBillType;
TextView tvPrice;
EditText txtBillID;
EditText txtPayID;
EditText txtPrice;


class C00661 implements OnClickListener {
    C00661() {
    }

    public void onClick(View v) {
        String payID = ActivityMain.this.txtPayID.getText().toString();
        String billID = ActivityMain.this.txtBillID.getText().toString();
        String myID = "124336";
        String price = ActivityMain.this.txtPrice.getText().toString();
        if (billID.length() == 0) {
            ActivityMain.this.showToast("\u0634\u0646\u0627\u0633\u0647 \u0642\u0628\u0636 \u0648\u0627\u0631\u062f \u0646\u0634\u062f\u0647 \u0627\u0633\u062a");
        } else if (payID.length() == 0) {
            ActivityMain.this.showToast("\u0634\u0646\u0627\u0633\u0647 \u067e\u0631\u062f\u0627\u062e\u062a \u0648\u0627\u0631\u062f \u0646\u0634\u062f\u0647 \u0627\u0633\u062a");
        } else if (price.length() == 0) {
            ActivityMain.this.showToast("\u0645\u0628\u0644\u063a \u0648\u0627\u0631\u062f \u0646\u0634\u062f\u0647 \u0627\u0633\u062a");
        } else {
            int i;
            int payIdLen = payID.length();
            for (i = 0; i < 13 - payIdLen; i++) {
                payID = "0" + payID;
            }
            int billIdLen = billID.length();
            for (i = 0; i < 13 - billIdLen; i++) {
                billID = "0" + billID;
            }
            Bill entityBillRercord = new Bill();
            entityBillRercord.billId = billID;
            entityBillRercord.createDate = Tools.getDate();
            entityBillRercord.payId = payID;
            entityBillRercord.refId = "";
            entityBillRercord.price = Tools.toInt(price);
            DbBills.insert(entityBillRercord);
            String encodeHash = Uri.encode("#");
            String ussd = "*733*3*2*" + billID + "*" + payID + "*" + encodeHash;
            ActivityMain.this.startActivityForResult(new Intent("android.intent.action.CALL", Uri.parse("tel:" + ussd)),1);
        }
    }
}


class Scanner implements OnClickListener {
    Scanner() {
    }

    @Override
    public void onClick(View v) {

        if (v.getId() == R.id.btnReadBarcode) {
            IntentIntegrator scanIntegrator = new IntentIntegrator(ActivityMain.this);
            scanIntegrator.initiateScan();
        }
    }
}


class C00683 implements OnClickListener {
    C00683() {
    }

    public void onClick(View v) {
        Intent intent = new Intent(ActivityMain.this, ActivitySupport.class);
        startActivity(intent);
        overridePendingTransition(R.anim.slide_in, R.anim.slide_out);

    }
}


class C00694 implements OnClickListener {
    C00694() {
    }

    public void onClick(View v) {
        Intent intent = new Intent("android.intent.action.SEND");
        intent.setType("text/plain");
        intent.putExtra("android.intent.extra.SUBJECT", "\u0646\u0631\u0645 \u0627\u0641\u0632\u0627\u0631 \u0647\u0645\u0647 \u0642\u0628\u0636");
        intent.putExtra("android.intent.extra.TEXT", "\u0646\u0631\u0645 \u0627\u0641\u0632\u0627\u0631 \u0647\u0645\u0647 \u0642\u0628\u0636\n\r\u067e\u0631\u062f\u0627\u062e\u062a \u0631\u0627\u062d\u062a \u0648 \u0622\u0633\u0627\u0646 \u06a9\u0644\u06cc\u0647 \u0642\u0628\u0648\u0636 \u0645\u062c\u0647\u0632 \u0628\u0647 \u0628\u0627\u0631\u06a9\u062f \u062e\u0648\u0627\u0646\n\r http://yealame.ir/upload/allbills.apk");
        ActivityMain.this.startActivity(Intent.createChooser(intent, "share"));
    }
}


class C00705 implements OnClickListener {
    C00705() {
    }

    public void onClick(View v) {
        Intent intent = new Intent(ActivityMain.this, ActivityRecords.class);
        startActivity(intent);
        overridePendingTransition(R.anim.slide_in, R.anim.slide_out);

    }
}


class C00716 implements TextWatcher {
    C00716() {
    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    public void afterTextChanged(Editable s) {
        String payID = ActivityMain.this.txtPayID.getText().toString();
        String price = "";
        if (payID.length() != 0) {
            int i;
            int payIdLen = payID.length();
            for (i = 0; i < 13 - payIdLen; i++) {
                payID = "0" + payID;
            }
            for (i = 0; i < 8; i++) {
                price = new StringBuilder(String.valueOf(price)).append(String.valueOf(payID.charAt(i))).toString();
            }
            price = String.valueOf(Tools.toInt(price));
            ActivityMain.this.txtPrice.setText(new StringBuilder(String.valueOf(price)).append("00").toString());
            ActivityMain.this.tvPrice.setText("\u0645\u0628\u0644\u063a \u0642\u0628\u0636: " + price + "00 \u062a\u0648\u0645\u0627\u0646");
        }
    }
}


class C00727 implements TextWatcher {
    C00727() {
    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    public void afterTextChanged(Editable s) {
        String billID = ActivityMain.this.txtBillID.getText().toString();
        int billIdLen = billID.length();
        if (billIdLen != 0) {
            for (int i = 0; i < 13 - billIdLen; i++) {
                billID = "0" + billID;
            }
            ActivityMain.this.setBillIcon(Tools.getBillIcon(billID));
        }
    }
}


class C00738 implements Runnable {
    C00738() {
    }

    public void run() {
        ActivityMain.this.doubleBackToExitPressedOnce = false;
    }
}

public ActivityMain() {
    this.doubleBackToExitPressedOnce = false;
}

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(1);
    setContentView(R.layout.main);
    setFont(findViewById(R.id.llMain));
    loadDb();
    this.btnPayBill = (Button) findViewById(R.id.btnPay);
    this.btnScanner = (Button) findViewById(R.id.btnReadBarcode);
    this.txtPayID = (EditText) findViewById(R.id.txtPayID);
    this.txtPrice = (EditText) findViewById(R.id.txtPrice);
    this.txtBillID = (EditText) findViewById(R.id.txtBillID);
    this.tvPrice = (TextView) findViewById(R.id.tvBillPrice);
    this.tvBillType = (TextView) findViewById(R.id.tvBillType);
    this.btnRecords = (Button) findViewById(R.id.btnRecords);
    this.btnLink = (Button) findViewById(R.id.btnLink);
    this.btnSupport = (Button) findViewById(R.id.btnSupport);
    setListeners();
}

private void loadDb() {
    this.myDbHelper = new DatabaseHelper2(this);
    try {
        this.myDbHelper.createDataBase();
    } catch (IOException e) {
    }
    try {
        this.myDbHelper.openDataBase();
    } catch (SQLException e2) {
    }
    BaseDataLayer.db = this.myDbHelper.getDB();
}

private void setListeners() {
    this.btnPayBill.setOnClickListener(new C00661());
    this.btnScanner.setOnClickListener(new Scanner());
    this.btnSupport.setOnClickListener(new C00683());
    this.btnLink.setOnClickListener(new C00694());
    this.btnRecords.setOnClickListener(new C00705());
    this.txtPayID.addTextChangedListener(new C00716());
    this.txtBillID.addTextChangedListener(new C00727());
}

private void setBillIcon(int billType) {
    switch (billType) {
        case CursorAdapter.FLAG_AUTO_REQUERY /*1*/:
            this.tvBillType.setBackgroundResource(R.drawable._bill_1_waterpng);
        case CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER /*2*/:
            this.tvBillType.setBackgroundResource(R.drawable._bill_2_electric);
        case TransportMediator.FLAG_KEY_MEDIA_FAST_FORWARD /*3*/:
            this.tvBillType.setBackgroundResource(R.drawable._bill_3_gas);
        case TransportMediator.FLAG_KEY_MEDIA_PLAY /*4*/:
            this.tvBillType.setBackgroundResource(R.drawable._bill_4_tel);
        default:
            this.tvBillType.setBackgroundDrawable(null);
    }
}

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
    if (scanningResult != null) {
        String scanContent = scanningResult.getContents();
        int contentsLen = scanContent.length();
        for (int i = 0; i < 26 - contentsLen; i++) {
            scanContent = "0" + scanContent;
        }
        if (scanContent != null) {
            String txtBillID = scanContent.substring(0, 13);
            String txtPayID = scanContent.substring(18);
            this.txtBillID.setText(txtBillID);
            this.txtPayID.setText(txtPayID);
            this.btnPayBill.setActivated(true);
        }
    } else {
        Toast toast = Toast.makeText(getApplicationContext(),
                "No scan data received!", Toast.LENGTH_SHORT);
        toast.show();
    }
}


public void onBackPressed() {
    if (this.doubleBackToExitPressedOnce) {
        super.onBackPressed();
        return;
    }
    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this, "\u0628\u0631\u0627\u06cc \u062e\u0631\u0648\u062c \u062f\u0648\u0628\u0627\u0631\u0647 \u06a9\u0644\u06cc\u062f \u0628\u0627\u0632\u06af\u0634\u062a \u0631\u0627 \u0628\u0632\u0646\u06cc\u062f", Toast.LENGTH_LONG).show();
    new Handler().postDelayed(new ActivityMain.C00738(), 2000);
}

enter image description here

Upvotes: 1

Views: 182

Answers (2)

W4R10CK
W4R10CK

Reputation: 5550

In Android Version > 23, you have to ask permission at run-time. You did not asked user about CALL_PHONE at run time and App crashed.

Something like this:

enter image description here

Learn more about asking permission at run time.

Upvotes: 1

Ankit Aman
Ankit Aman

Reputation: 1009

From SDK version 23 and above you have to ask for runtime permission to the users.It is mandatory to ask from API level 23 and above.

You can use this code and if boolean is true then it will allow you to call.

before this line

if (requestCallPhonePermission(this)) {
ActivityMain.this.startActivityForResult(new Intent("android.intent.action.CALL", Uri.parse("tel:" + ussd)),1);
}  


@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static boolean requestCallPhonePermission(final Context context) {
    if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        String callPhonePermission = Manifest.permission.CALL_PHONE;
        int hasPermission = ContextCompat.checkSelfPermission(context, callPhonePermission);
        final String[] permissions = new String[]{callPhonePermission};
        if (hasPermission != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions((Activity) context, permissions, PERMISSION_REQUEST_CALL_PHONE);
            return false;
        } else {
            return true;
        }
    }
    return true;
}

and in same activity to receive permission put this as well.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CALL_PHONE:
            if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Snackbar snackbar = Snackbar.make(CoordResident, R.string.permission_goto_setting, Snackbar.LENGTH_LONG);
                snackbar.setAction("Settings", new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // open settings to enable permisions 
                    }
                });
                snackbar.show();
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Upvotes: 0

Related Questions