I am retrieving the outgoing number from the broadcast receiver and trying to send it to the activity thru a method getNumber() however the value is coming out null. Im my code below In the activity class the String phonenumber is null
BroadcastReciever Class:
public class OutgoingBroadcastReceiver extends BroadcastReceiver {
String phonenumber = null;
#Override
public void onReceive(Context context, Intent intent) {
phonenumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL"))
{
Log.i("System out", "IN OUTGOING CALL......... :IF");
MyPhoneStateListener phoneListener = new MyPhoneStateListener(
context);
TelephonyManager telephony = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener,
PhoneStateListener.LISTEN_CALL_STATE);
} else {
Log.i("System out", "IN INCOMING CALL.........:else:receiver");
}
public String getNumber()
{
return phonenumber;
}
Activity Class:
public class OutgoingCallScreenDisplay extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.outgoing_main);
OutgoingBroadcastReceiver outreciever = new OutgoingBroadcastReceiver();
String phonenumber= outreciever.getNumber();//this is coming out NULL needs to be the outgoing number
}
Phone no. is null because u r making a new instance of broadcastreceiver whose values are not initilized. You can receive a phone no. in "onReceive" ONLY ,from there u should start a new activity if u want to pass it further
See:
Firstly you shud either use a broadcast receiver or a phone state listener. In ur case if u r using a broadcast receiver then u simple need intent extra:EXTRA_PHONE_NUMBER
and permission : process outgoin call .That's it.....
Two things immediately come to mind:
The onReceive method needs to be called before you can get the phone number.
You are assigning the phone number to a local variable and not the instance member.
use putExtra if you want to pass data to an activity
Related
I am using the quickstart-android code provided by google but after many attempts I cam unable to find a context that is not returning null. The BarcodeScannerProcessor is not itself an Activity, so I have attempted to create an instance of the LivePreviewActivity and use that as the context in the intent, but it's null.
The goal is to once a valid barcode is recognized I want to open a new activity that allows a user to verify value and on the push of a button call a webservice to post the barcode to a database via API. I am having a hard time finding a valid context and the app is crashing when it trys to execute the Intent.
Starting at line 97-107:
https://github.com/jamiekeefer/quickstart-android/blob/master/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/java/barcodescanning/BarcodeScanningProcessor.java
for (int i = 0; i < barcodes.size(); ++i) {
FirebaseVisionBarcode barcode = barcodes.get(i);
BarcodeGraphic barcodeGraphic = new BarcodeGraphic(graphicOverlay, barcode);
graphicOverlay.add(barcodeGraphic);
System.out.println(barcode.getRawValue());
if (!barcode.getRawValue().equals("") ) {
System.out.println("Got the number:" + barcode.getRawValue() + " Context: " + mContext); //OLD SCHOOL DEBUG OUTPUT
//enter code to start activity
Intent intent = new Intent(mContext, SendScannedBarcode.class);
String message = scannedBarcode;
intent.putExtra(EXTRA_MESSAGE, message);
mContext.startActivity(intent);
}
}
You can back up in the repo to see the instance of the LivePreviewActivity where I trying to get context.
I have tried a number of things and read about Context, Views and Activities and basically have completely confused myself. The only tuts I can find are using Kotlin, which is not helping clarify things.
I appreacite any help in indentifying or contruting a valid Intent from this Context. Thank you.
So I am assuming that in your LivePreviewActivity you are creating an object of the class BarcodeScanningProcessor. What you can do is change the constructor in the BarcodeScanningProcessor class to accept a context and then you pass in your LivePreviewActivity's context.
This is what the code should look like:
In BarcodeScanningProcessor:
public BarcodeScanningProcessor(Context context) {
// Note that if you know which format of barcode your app is dealing with, detection will be
// faster to specify the supported barcode formats one by one, e.g.
// new FirebaseVisionBarcodeDetectorOptions.Builder()
// .setBarcodeFormats(FirebaseVisionBarcode.FORMAT_QR_CODE)
// .build();
detector = FirebaseVision.getInstance().getVisionBarcodeDetector();
this.mContext = context;
}
Then in LivePreviewActivity:
In the particular case of your activity you would do:
case BARCODE_DETECTION:
Log.i(TAG, "Using Barcode Detector Processor");
cameraSource.setMachineLearningFrameProcessor(new BarcodeScanningProcessor(getApplicationContext()));
break;
Or if you just wanted to create an object of the class you could do:
BarcodeScanningProcessor bsp = new BarcodeScanningProcessor(getApplicationContext());
This should now give your BarcodeScanningProcessor class the context of your activity. Now, in BarcodeScanningProcessor, mContext should not be null and will have the context of your activity. I hope this answers your question.
try this create Application class
import android.app.Application;
public class MyApplication extends Application {
static MyApplication instance;
#Override
public void onCreate() {
super.onCreate();
instance=this;
}
public static MyApplication getInstance() {
return instance;
}
}
Register in manifest file
<application
..
android:name="com.yourpackage.MyApplication"
..>
.
.
.
</application>
start activity using this MyApplication.
Intent intent = new Intent(MyApplication.getInstance(), SendScannedBarcode.class);
String message = scannedBarcode;
intent.putExtra(EXTRA_MESSAGE, message);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MyApplication. getInstance().startActivity(intent);
Another way of handling the issue is create new constructor of BarcodeScanningProcessor which takes interface call back and once processing is done pass back result to caller.
public interface BarcodeUpdateListener {
#UiThread
void onBarcodeDetected(Barcode barcode);
}
private BarcodeUpdateListener callback;
public BarcodeScanningProcessor(BarcodeUpdateListener callback){
this.callback = callback;
detector = FirebaseVision.getInstance().getVisionBarcodeDetector();
}
Once you get the result pass result to caller
callback.onBarcodeDetected(<Barcode>)
You can get the context from graphicOverlay:
Context context = graphicOverlay.getContext();
I found some interesting methods in telephonyManager class like turning mobile data off/on but when trying to use them it obviously throws me security exception.("No carrier privilege"). I Googled it, but didn't find any helpful solution.
Because it's carrier privilege I thought it may be possible to get its permission by telephonyManager.getIccAuthentication(int appType, int authType, String data) but I'm having problems with input parameters because I can't figure out what should I pass in to make it work.
From documentation to the first parameter would pass TelephonyManager.APPTYPE_SIM or/and TelephonyManager.APPTYPE_USIM depending on if it has big meaning in using setDataEnabled(boolean).
If I would pass TelephonyManager.APPTYPE_SIM as a first argument I think I should passed TelephonyManager.AUTHTYPE_EAP_SIM as a second argument (correct me if I'm wrong) and vice versa, when TelephonyManager.APPTYPE_USIM as first so TelephonyManager.AUTHTYPE_EAP_AKA as second one.
And then there is the third argument. There must be encoded Base64 to string. I found in TelephonyProvider this line of code:
String base64Challenge = Base64.encodeToString(byteParam, Base64.NO_WRAP); where byteParam is an input byte from another method which is being preceding by thousands other methods. If I pass "" as third parameter to getIccAuthentication method I get again securityException (it's obviously, wrong param) but it throws me lack of getIccSimChallengeResponse. I'm afraid of it may be infinite loop of methods, but maybe someone has any idea or help me to break this through?
My sample code:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.buttonPanel);
button.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onClick(View view) {
try {
Process p = Runtime.getRuntime().exec("su");
tel();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void tel(){
// String base64Challenge = Base64.encodeToString(,
Base64.NO_WRAP);
TelephonyManager telephonyManager = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
boolean isCarrier = telephonyManager.hasCarrierPrivileges();
String authentication =
telephonyManager.getIccAuthentication(TelephonyManager.APPTYPE_SIM,
TelephonyManager.AUTHTYPE_EAP_SIM, "");
Log.v(TAG, authentication);
if (isCarrier) {
Log.v(TAG, "privs granted");
telephonyManager.setDataEnabled(false);
} else {
Log.v(TAG, "no privilegies");
}
}
}
From the docs:
Requires Permission: READ_PRIVILEGED_PHONE_STATE or that the calling
app has carrier privileges (see hasCarrierPrivileges()).
The first of those requires you to be installed as a privileged system app (requires root or owning system certificate). The second requires your UID to be the carrier's. Without that no combo of parameters will work.
I try to save and return the value i've got from the broadcast receiver method i wrote, but it wont work. Peculiarly using Log inside the receiver to print the value works fine, but i cant save the value.
Hope someone got a simple solution for me.
//Gives current battery temperature in celsius
public String getBatteryTemperature()
{
final int[] batTemp = new int[1];
BroadcastReceiver batteryTemperatureReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
batTemp[0] = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,0)/10;
//optional Log output for debug (works)
Log.i("Log battery temperature", String.valueOf(batTemp[0]) + "°C");
}
};
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
this.getContext().registerReceiver(batteryTemperatureReceiver, intentFilter);
//only returns 0
return String.valueOf(batTemp[0]);
}
This is because your method returns before you receive a notification. In this case, your receiver class has just a local scope but includes a reference to the enclosing class (which I assume an Activity) and it's doesn't get destroyed when you're out of the method.
So you can make it a member variable.
I'm making an Android App with Google Spreadsheets. I'm scanning a barcode from a book, looking the info with the Google Books API and then I need to save this info into a sheet.
The following code is inside MainActivity:
private class GetBookInfo extends AsyncTask <String, Void, String> {
#Override
protected String doInBackground(String... urls) {
// make Call to the url
makeCall("https://www.googleapis.com/books/v1/volumes?" +
"q=isbn:" + ean_content + "&AIzaSyCpYez5556X4UzPV6rF4kkspj9DsCs_Q_c");
//print the call in the console
System.out.println("https://www.googleapis.com/books/v1/volumes?" +
"q=isbn:" + ean_content + "&AIzaSyCpYez5556X4UzPV6rF4kkspj9DsCs_Q_c");
return null;
}
#Override
protected void onPreExecute() {
// we can start a progress bar here
}
#Override
protected void onPostExecute(String result) {
String ruta = save_cover(getApplicationContext(), title, book_cover);
Intent intent = new Intent(MainActivity.this, Spreadsheets.class);
finish();
startActivity(intent);
}
}
After this code I have public void makeCall(String stringURL). It searchs the book's title, author, date, description and category of the book.
I have another Activity:
public class Spreadsheets extends Activity implements EasyPermissions.PermissionCallbacks
In this activity, I have the following code to write into a Google Sheet:
public void setDataToApi (String title, String author, String date, String category, String description) throws IOException {
String spreadsheetId = "1Gg121IjABekfSTKXg_TQzJgg4boxvYIQnmf_K4YDboo";
String range = "Sheet1!A2:E2";
List<List<Object>> values = new ArrayList<>();
List<Object> data1 = new ArrayList<>();
data1.add(title);
data1.add(author);
data1.add(date);
data1.add(category);
data1.add(description);
values.add(data1);
ValueRange valueRange = new ValueRange();
valueRange.setMajorDimension("ROWS");
valueRange.setRange(range);
valueRange.setValues(values);
UpdateValuesResponse response = this.mService.spreadsheets().values().update(spreadsheetId, range, valueRange)
.setValueInputOption("RAW")
.execute();
System.out.printf("%d cells updated.", response.getUpdatedCells());
}
My problem is that I'm trying to call the setDataToApi method from the onPostExecute method, before the intent, but it does not work at all. Thank you very much!
You cannot call the method of another Activity from outside that Activity. Before the Intent is actually dispatched, the other Activity is not yet running. You either need to
Move GetBookInfo to the SpreadSheets Activity so that it can perform the onPostExecute directly in the Activity. This requires passing the book's ID via an extra on the Intent. Or...
Keep GetBookInfo where it is in MainActivity and pass all the looked up details of the book through extras on the Intent.
If you have a method being called from 2 different activities, I would recommend putting that method in a separate class. So move setDataToApi into it's own Java class, instantiate an object of your new class and use that method in both of your activities that call it.
Or, as Elan said in their answer, use intents and pass information to your other activity using putExtra and write your own logic in the onCreate method to call setDataToApi. Hope this helps!
I am working on an Android project in which I am trying to integrate PUSH service offered by Cometd framework.
Now, whenever a new message arrives for a Conversation, I would like to inform ChatMessagesActivity which contains the list of messages between the two users.
Now, when the other user sends a message to the Android app, I would like to update the view of the user. I tried doing that by calling notifyDataSetHasChanged() on the adapter, but because I was calling it outside of View thread, I am getting an error.
The method is static, because new messages are received in Conversation class, while the messages are going-on in ChatMessagesActivity class. For communication between both classes, I have created 2 static methods which act like a bi-directional bridge for sending & receiving messages.
I hope I was clear, if there are any doubts, kindly let me know.
ChatMessagesActivity.java :
public class ChatMessagesActivity extends ApplicationDrawerLoader {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_messages);
chatList = (ListView)findViewById(R.id.chatList);
new getPrivateChatsForUser(this).execute();
}
// IN the method below, I receive information from another activity.
public static void recieveUpdatedMessage(String channelName, Map<String, Object> input){
Boolean found = Arrays.asList(channelName.split(" ")).contains("chat");
if(found){
int processedChannelName = Integer.valueOf(channelName.replace("/chat/",""));
if(processedChannelName == groupAccountId){
// Here i tried calling adapter.NotifyDataSetchanged();.. Didn't fly.
}
}
}
// Async method retrieving messages.
public class getPrivateChatsForUser extends AsyncTask<Void, Void, ResponseEntity<RestReplies[]>> {
ChatMessagesActivity chatMessagesActivity = null;
getPrivateChatsForUser(ChatMessagesActivity chatMessagesActivity) {
this.chatMessagesActivity = chatMessagesActivity;
}
#Override
protected ResponseEntity<RestReplies[]> doInBackground(Void... params) {
// network connection related stuff, not relevant to problem
}
#Override
protected void onPostExecute(ResponseEntity<RestReplies[]> responseEntity) {
super.onPostExecute(responseEntity);
RestReplies[] restRepliesArray = responseEntity.getBody();
Collections.addAll(restRepliesList, restRepliesArray);
ArrayList<HashMap<String, String>> chatMessagesHashMapList = new ArrayList<HashMap<String, String>>();
for (RestReplies restReplies : restRepliesList) {
HashMap<String, String> chatMap = new HashMap<>();
chatMap.put(chatText, restReplies.getReplyText());
chatMap.put(firstName, restReplies.getReplyingPersonName());
chatMap.put(chatImage, restReplies.getSenderImage());
chatMap.put(privateChannel,"/service/person/"+String.valueOf(conversationId));
chatMessagesHashMapList.add(chatMap);
}
chatList = (ListView) findViewById(R.id.chatList);
chatMessagesAdapter = new ChatMessagesAdapter(chatMessagesActivity, chatMessagesHashMapList);
chatList.setAdapter(chatMessagesAdapter);
chatList.scrollTo(0, chatList.getHeight());
}
}
So, how should I instruct that the data-set has been changed.. And how does the adapter knows where and how to get the data-set which has changed. Can anyone help me with this problem. Thanks a lot... :-)
Use broadcast receiver at your adapter and fire a local broadcast with android LocalBroadcast in your push service
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals("MYREFRESH"))
{
notifiyDataSetChanged();
}
}
};
In your constructor in adapter register this reciever
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("MYREFRESH");
LocalBroadcastManager.getInstance(context).registerReceiver(broadReceiver, intentFilter);
In your push if you get a push notification trigger this
Intent intent = new Intent();
intent.putExtra(...) //send any data to your adapter
Intent.setAction("myaction");
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
The way to deal with this is using a broadcast or bus pattern. You can use some good bus libraries such as http://square.github.io/otto/ or a LocalBroadcast
This past answer from me shows how to use the LocalBroadcast system: Refreshing fragments in FragmentActivity after sync service runs