Cannot find symbol in extension

Hello.
I try to write an extension. so I code it in Android studio to tune it and make it works,
but when i copy it in AppyBuilder, I have some errors, "cannot find symbol":

[javac] /projects/goldv2/appinventor-sources/appinventor/components/src/com/appybuilder/jmlat/PhoneCall/PhoneCall.java:55: error: cannot find symbol
[javac]         TelecomManager tm = (TelecomManager) this.getSystemService(Context.TELECOM_SERVICE);

I have
`import android.telecom.TelecomManager;

and it works well in Android studio...
is someone knows where is the trouble ?
`

You have to import Telecom manager and then initialize It.

ok. how can i do this ?

Since your class does not extend Activity or Context so you can't access those method directly or by using this .
Initialize a context variable and replace this with context.

1 Like

I just have to write Context context ?? but what is in context ?

sorry but i didn't really understood what is context and how it works...

Practise makes a man perfect so better is to learn from practise.
You can check below code to understand how to work with context:
https://github.com/vknow360/Picasso/blob/main/Picasso.java

3 Likes

Thanks for helping me with context.
but it seems that it is not the only problem:
now I have:

[javac] /projects/goldv2/appinventor-sources/appinventor/components/src/com/appybuilder/jmlat/PhoneCall/PhoneCall.java:71: error: package Manifest does not exist

Import this:

android.Manifest;

great ! now i Have no Manifest error any more...
but it seems it can't use it because now it is

PhoneCall.java:60: error: cannot find symbol
[javac]             boolean success = tm.endCall();

where tm is :

TelecomManager tm = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);

You should post the relevant code here..
Only reason for that error can be that endCall() method does not exist.

Here is my code on AppyBuilder

 import android.content.Context;
 import android.util.Log;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.runtime.*;
import com.google.appinventor.components.common.ComponentCategory;
import android.telecom.TelecomManager;
import android.Manifest;
import android.content.Intent;
import android.net.Uri;


@DesignerComponent(version = 1,  description = "This Extension was created with the AppyBuilder Code Editor.<br>" + 
               "Create your own here:<br><a href='https://editor.appybuilder.com' target='_blank'>https://editor.appybuilder.com</a><br>",
    category = ComponentCategory.EXTENSION,
    nonVisible = true,   iconName = "http://appyBuilder.com/extensions/icons/extension.png")
 @SimpleObject(external = true)
public class PhoneCall extends AndroidNonvisibleComponent {
private ComponentContainer container;
  public Context context;
/**
 * @param container container, component will be placed in
 */
public PhoneCall(ComponentContainer container) {
    super(container.$form());
    this.container = container;
  context = container.$context();
}

  @SimpleFunction(description = "Stores a value in TinyDB")
public void StoreValue(final String tag, final String valueToStore) {
    TinyDB tinyDB = new TinyDB(container);
    tinyDB.StoreValue(tag, valueToStore);
}

@SimpleFunction(description = "Retrieves value of a tag")
public Object GetValue(final String tag, final Object valueIfTagNotThere) {
    TinyDB tinyDB = new TinyDB(container);
    return tinyDB.GetValue(tag, valueIfTagNotThere);
}

@SimpleFunction(description = "EndCall")
  //@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
void EndCall() {
    TelecomManager tm = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);

    if (tm != null) {
        boolean success = tm.endCall();
        // success == true if call was terminated.
        Log.d("JML", "Raccroché  **" + success);
    }
}

@SimpleFunction(description = "AcceptRingingCall")
void AcceptRingingCall() {
    TelecomManager tm = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);

    if (tm != null) {
        if (ActivityCompat.checkSelfPermission(context,Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        tm.acceptRingingCall();
        Log.d("JML","acceptRingingCall   **" );
    }
}
@SimpleFunction(description = "Call")
void Call(String num){
    Intent i = new Intent(Intent.ACTION_CALL);
    i.setData(Uri.parse("tel:" + num));
    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    startActivity(i);
}
}

And this code in Android Studio for testing which works well

package jml.outilsgestionappeltelephone;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.telecom.TelecomManager;
import android.util.Log;


public class MainActivity extends AppCompatActivity {

String message;
String numero;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1);
    }
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ANSWER_PHONE_CALLS}, 1);
    }
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1);
    }

    // Get the Intent that started this activity and extract the string
    Intent intent = getIntent();
    message = intent.getStringExtra("MessageRecu");
    numero = intent.getStringExtra("Numéro");
    Log.d("outilsgestionappeltelephone", "MessageRecu  ** : " + message);
    if (message != null) {
        switch (message) {
            case "FinAppel":
                Log.d("outilsgestionappeltelephone", "endCall  ** : " + message);
                endCall();
                closeApp();
                break;
            case "DĂ©croche":
                Log.d("outilsgestionappeltelephone", "acceptRingingCall  ** : " + message);
                acceptRingingCall();
                closeApp();
                break;
            case "Appeler":
                Log.d("outilsgestionappeltelephone", "call  ** : " + numero);
                call();
                closeApp();
                break;
            default:
                break;
        }
    }

}


@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
void endCall() {
    TelecomManager tm = (TelecomManager) getBaseContext().getSystemService(Context.TELECOM_SERVICE);

    if (tm != null) {
        boolean success = tm.endCall();
        // success == true if call was terminated.
        Log.d("JML", "Raccroché  **" + success);
    }
}

void acceptRingingCall() {
    TelecomManager tm = (TelecomManager) getBaseContext().getSystemService(Context.TELECOM_SERVICE);

    if (tm != null) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        tm.acceptRingingCall();
        Log.d("JML","acceptRingingCall   **" );
    }
}

void call(){
    Intent i = new Intent(Intent.ACTION_CALL);
    i.setData(Uri.parse("tel:" + numero));
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    startActivity(i);
}

void closeApp(){
    finish();
    //moveTaskToBack(true);
}

}

endCall() method was added in API 28 and got deprecated in API 29.
It is not going to work.