im kinda new to android, im trying to use jsoup to parse a html page to gather some info from a page.
i would like to insert a url via pop-up (altertbox) usinga method called loadwebsite:
private void loadWebsite(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Inserisci url sito");
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
linkurl = input.getText().toString();
//linkurl="https://"+linkurl;
url123.setText("https://"+linkurl.toString());
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
and a method called getsiteinfo()
private void getinfoWebsite(){
new Thread(new Runnable() {
#Override
public void run() {
final StringBuilder builder = new StringBuilder();
try {
Document doc = Jsoup.connect(linkurl).get();
String title = doc.title();
Element image = doc.select("img").first();
String imgSrc = image.absUrl("src");
InputStream in = new java.net.URL(imgSrc).openStream();
bitmap = BitmapFactory.decodeStream(in);
builder.append(title).append("\n");
} catch (IOException e){
builder.append("Error :").append(e.getMessage()).append("\n");
}
runOnUiThread(new Runnable() {
#Override
public void run() {
result.setText(builder.toString());
}
});
}
}).start();
}
the problem is that when i try to pass a url via textbox i get that error:
03-26 17:22:16.826 26651-26840/it.uninsubria.pdm.htmlparsingjsoup E/AndroidRuntime: FATAL EXCEPTION: Thread-8
Process: it.uninsubria.pdm.htmlparsingjsoup, PID: 26651
java.lang.IllegalArgumentException: Must supply a valid URL
at org.jsoup.helper.Validate.notEmpty(Validate.java:102)
at org.jsoup.helper.HttpConnection.url(HttpConnection.java:72)
at org.jsoup.helper.HttpConnection.connect(HttpConnection.java:36)
at org.jsoup.Jsoup.connect(Jsoup.java:73)
at it.uninsubria.pdm.htmlparsingjsoup.MainActivity$3.run(MainActivity.java:78)
at java.lang.Thread.run(Thread.java:764)
here is the full code:
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Tag;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
private Button getBtn;
private TextView result;
private ImageView img;
private Bitmap bitmap;
private Button button2;
private String linkurl = "";
private TextView url123;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
result = (TextView) findViewById(R.id.result);
img= (ImageView) findViewById(R.id.image2);
url123 =(TextView)findViewById(R.id.url123);
getBtn =(Button) findViewById(R.id.button2); //
getBtn.setOnClickListener(new View.OnClickListener() { // Pulsante "open website
#Override //
public void onClick(View v) {
openWebsite();
}
});
getBtn =(Button) findViewById(R.id.getBtn);
getBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadWebsite();
getinfoWebsite();
img.setImageBitmap(bitmap);
}
});
}
//////////////////////////////////////////// -------------------METHODS------------------////////////////////////////////////////////
private void getinfoWebsite(){
new Thread(new Runnable() {
#Override
public void run() {
final StringBuilder builder = new StringBuilder();
try {
Document doc = Jsoup.connect(linkurl).get();
String title = doc.title();
Element image = doc.select("img").first();
String imgSrc = image.absUrl("src");
InputStream in = new java.net.URL(imgSrc).openStream();
bitmap = BitmapFactory.decodeStream(in);
builder.append(title).append("\n");
} catch (IOException e){
builder.append("Error :").append(e.getMessage()).append("\n");
}
runOnUiThread(new Runnable() {
#Override
public void run() {
result.setText(builder.toString());
}
});
}
}).start();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void openWebsite(){
Uri uriUrl = Uri.parse(String.valueOf(linkurl));
Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
startActivity(launchBrowser);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//pop-up text per caricare link url
private void loadWebsite(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Inserisci url sito");
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
linkurl = input.getText().toString();
//linkurl="https://"+linkurl;
url123.setText("https://"+linkurl.toString());
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
}
The error says that the argument you are passing to Jsoup.connect is not valid (empty). It looks like you creating onClick listener to set value of linkurl, but you are starting parsing thread immediately, i.e. not waiting for linkurl value to be set. You can for example delay execution of the code by inserting this code in the begining of run method inside getinfoWebsite(): while(linkurl.isEmpty()) { Thread.sleep(1000);}
Related
I am trying to code an inventory app that can work on UROVO DT40 device. I don't know how to code the barcode scanner so that it will work on keystroke and send the result to edittext. I also want to save the data from the adapter and be able to read from a PC. I am still a rookie so I don't know if am doing it the right way. I need some help please. Thanks!!
here's some of the code
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.google.android.material.textfield.TextInputEditText;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {ArrayList<String>
listitems = new ArrayList<>();
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextInputEditText input = findViewById(R.id.textInputEditText);
TextInputEditText input1 = findViewById(R.id.textInputEditText1);
ListView listview = findViewById(R.id.listView);
Button saveBtn = findViewById(R.id.saveBtn);
Button btn_annuler = findViewById(R.id.btn_annuler);
Button OK = findViewById(R.id.btn3);
Button btn2 = findViewById(R.id.btn2) ;
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,listitems);
listview.setAdapter(adapter);
input.setShowSoftInputOnFocus(false);
input1.setShowSoftInputOnFocus(false);
OK.setOnClickListener(v -> {
listitems.add(Objects.requireNonNull(input.getText()).toString() + ';' + Objects.requireNonNull(input1.getText()).toString());
adapter.notifyDataSetChanged();
input.setText("");
input1.setText("");
});
btn_annuler.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
input.setText("");
input1.setText("");
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
adapter.clear();
}
});
saveBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!adapter.toString().equals(""))
{
String data = adapter.toString();
writeToFile(data);
Toast.makeText(MainActivity.this, "Vidage éffectué!", Toast.LENGTH_LONG).show();
}
}
});
}
private void writeToFile(String data) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("ficGloba.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
There are code samples on the Urovo github page for the Android SDK, specifically also one for the Scanner
Steps 1 to 4 from from the ScannerManagerDemo.java javadoc describe how you have to setup the Scanner:
1.Obtain an instance of BarCodeReader with ScanManager scan = new ScanManager().
2.Call openScanner to power on the barcode reader.
3.After that, the default output mode is TextBox Mode that send barcode data to the focused text box. User can check the output mode
using getOutputMode and set the output mode using switchOutputMode.
4.Then, the default trigger mode is manually trigger signal. User can check the trigger mode using getTriggerMode and set the trigger mode
using setTriggerMode.
for full completeness, the extracted javacode:
private void initScan() {
mScanManager = new ScanManager();
boolean powerOn = mScanManager.getScannerState();
if (!powerOn) {
powerOn = mScanManager.openScanner();
if (!powerOn) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Scanner cannot be turned on!");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog mAlertDialog = builder.create();
mAlertDialog.show();
}
}
initBarcodeParameters();
}
That should give you enough to get cracking. Godspeed.
This is such a basic issue that I am not sure what I could possibly be doing wrong. Sinch is not starting for me and I don't know why. I don't have enough experience with Sinch to diagnose why a basic command is not doing what it is supposed to do. Here's what I have:
I am trying to start and making the call from the Calling.java class. The code is as follows:
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.sinch.android.rtc.calling.Call;
import com.squareup.picasso.Picasso;
import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
public class Calling extends CallActivity {
private String calleeID;
private TextView serviceName;
Bundle callDetails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calling);
callDetails = getIntent().getBundleExtra("callDetails");
//Setup end button
Button endCallButton = findViewById(R.id.endcall);
endCallButton.setOnClickListener(v -> endCall());
}
private void endCall() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
finishActivity(FLAG_ACTIVITY_PREVIOUS_IS_TOP);
finish();
}
// invoked when the connection with SinchServer is established
#Override
protected void onServiceConnected() {
//Setup Calling Screen
ImageView avatar = findViewById(R.id.dialingAvatar);
Picasso.get().load(callDetails.getString("Logo")).into(avatar);
TextView midScreenName = findViewById(R.id.memberName);
midScreenName.setText(callDetails.getString("Name"));
serviceName = findViewById(R.id.serviceName);
serviceName.setText(callDetails.getString("Service"));
TextView ratings = findViewById(R.id.rating);
ratings.setText(callDetails.getString("Rating") + " ★");
//Get CallerID and CalleeID
calleeID = callDetails.getString("CalleeID");
//Start sinch Service
if(!getSinchServiceInterface().isStarted()){
getSinchServiceInterface().startClient(callDetails.getString("CallerID"));
Call call = getSinchServiceInterface().callUserVideo(calleeID);
Intent callServiceScreen = new Intent(this, ServiceCallActivity.class);
callDetails.putString(SinchService.CALL_ID, call.getCallId());
callServiceScreen.putExtra("Call Details", callDetails);
startActivity(callServiceScreen);
}
}
#Override
public void onDestroy() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
super.onDestroy();
}
}
I am coming to Calling.java from Precall.java the code for that is:
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.sinch.android.rtc.SinchError;
import com.squareup.picasso.Picasso;
import org.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class precall extends CallActivity implements SinchService.StartFailedListener {
private Bundle memberDetails;
private String url;
private Button cancel;
private Button call;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_precall);
//url
url = apiCallPoints.userInfo;
//Set Member Text
memberDetails = getIntent().getBundleExtra("Member");
//Populate screen
ImageView avatar = findViewById(R.id.avatar);
Picasso.get().load(memberDetails.getString("Logo")).into(avatar);
TextView memberName = findViewById(R.id.membername);
memberName.setText(memberDetails.getString("Name"));
TextView rating = findViewById(R.id.rating);
rating.setText(memberDetails.getString("Rating") + " ★");
TextView serviceName = findViewById(R.id.servicename);
serviceName.setText(memberDetails.getString("Service"));
TextView overview = findViewById(R.id.overview);
overview.setText(memberDetails.getString("Overview"));
//Add button clicks
cancel = findViewById(R.id.cancel_button);
cancel.setOnClickListener(view -> finish());
cancel.setEnabled(false);
call = findViewById(R.id.yes_button);
call.setOnClickListener(view -> {
goToCalling();
});
call.setEnabled(false);
setHomeBar();
}
//this method is invoked when the connection is established with the SinchService
#Override
protected void onServiceConnected() {
call.setEnabled(true);
cancel.setEnabled(true);
getSinchServiceInterface().setStartListener(this);
}
#Override
protected void onPause() {
super.onPause();
}
#Override
public void onStartFailed(SinchError error) {
}
//Invoked when just after the service is connected with Sinch
#Override
public void onStarted() {
}
private void goToCalling() {
//Async search
CallBackendSync callBackendSync = new CallBackendSync();
Object [] params = {url, memberDetails};
callBackendSync.execute(params);
}
private void setHomeBar() {
final Button home = findViewById(R.id.home_button);
home.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, SecondActivity.class));
}
});
final Button favourites = findViewById(R.id.star_button);
favourites.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, Favourite_Page.class));
}
});
final Button profile_page = findViewById(R.id.person_button);
profile_page.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(getApplicationContext(), Profile.class));
}
});
final Button notifications = findViewById(R.id.notification_button);
notifications.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, Notification_Page.class));
}
});
final Button service = findViewById(R.id.service_button);
service.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
startActivity(new Intent(precall.this, services.class));
}
});
}
class CallBackendSync extends AsyncTask {
OkHttpClient client = new OkHttpClient();
#Override
protected Object doInBackground(Object [] objects) {
String url = (String) objects[0];
Bundle memberDetails = (Bundle) objects[1];
//Get access token from shared preference
isLoggedIn loggedIn = new isLoggedIn(getApplicationContext());
String token = loggedIn.getToken();
if(token != null){
//Create request
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer " + token)
.addHeader("Accept", "application/json")
.build();
try {
Response response = client.newCall(request).execute();
JSONObject results = new JSONObject(response.body().string());
String UserID = results.getString("UserId");
memberDetails.putString("CallerID", UserID);
Intent callIntent = new Intent(precall.this, Calling.class);
callIntent.putExtra("callDetails", memberDetails);
startActivity(callIntent);
return results;
}catch (Exception e){
e.printStackTrace();
}
} else {
startActivity(new Intent(precall.this, Login_page.class));
}
return null;
}
protected void onPostExecute(String s){
super.onPostExecute(s);
}
}
}
The failure is happening in SinchService.java
import com.sinch.android.rtc.AudioController;
import com.sinch.android.rtc.ClientRegistration;
import com.sinch.android.rtc.Sinch;
import com.sinch.android.rtc.SinchClient;
import com.sinch.android.rtc.SinchClientListener;
import com.sinch.android.rtc.SinchError;
import com.sinch.android.rtc.video.VideoController;
import com.sinch.android.rtc.calling.Call;
import com.sinch.android.rtc.calling.CallClient;
import com.sinch.android.rtc.calling.CallClientListener;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class SinchService extends Service {
private static final String APP_KEY = "is correct";
private static final String APP_SECRET = "is correct";
//private static final String ENVIRONMENT = "clientapi.sinch.com";
private static final String ENVIRONMENT = "sandbox.sinch.com";
public static final String CALL_ID = "CALL_ID";
static final String TAG = SinchService.class.getSimpleName();
private SinchServiceInterface mSinchServiceInterface = new SinchServiceInterface();
private SinchClient mSinchClient = null;
private String mUserId = "";
private StartFailedListener mListener;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
if(mSinchClient != null){
mSinchClient.terminate();
}
super.onDestroy();
}
private void start(String userName) {
mUserId = userName;
mSinchClient = Sinch.getSinchClientBuilder().context(getApplicationContext())
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT)
.userId(userName)
.enableVideoCalls(true)
.build();
mSinchClient.setSupportCalling(true);
mSinchClient.startListeningOnActiveConnection();
mSinchClient.addSinchClientListener(new MySinchClientListener());
mSinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
mSinchClient.checkManifest();
mSinchClient.start();
System.out.println("Is started: " + mSinchClient.isStarted());
}
private void stop() {
if(mSinchClient != null){
mSinchClient.terminate();
}
}
private boolean isStarted() {
if(mSinchClient != null){
return mSinchClient.isStarted();
} else {
return false;
}
}
#Override
public IBinder onBind(Intent intent) {
return mSinchServiceInterface;
}
public class SinchServiceInterface extends Binder {
public Call callUserVideo(String userId) {
return mSinchClient.getCallClient().callUserVideo(userId);
}
public String getUserName() {
return mUserId;
}
public boolean isStarted() {
return SinchService.this.isStarted();
}
public void startClient(String userName) {
start(userName);
}
public void stopClient() {
stop();
}
public void setStartListener(StartFailedListener listener) {
mListener = listener;
}
public Call getCall(String callId) {
return mSinchClient.getCallClient().getCall(callId);
}
public VideoController getVideoController() {
return mSinchClient.getVideoController();
}
public AudioController getAudioController() {
return mSinchClient.getAudioController();
}
}
public interface StartFailedListener {
void onStartFailed(SinchError error);
void onStarted();
}
private class MySinchClientListener implements SinchClientListener {
#Override
public void onClientFailed(SinchClient client, SinchError error) {
if (mListener != null) {
mListener.onStartFailed(error);
}
mSinchClient.terminate();
mSinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
Log.d(TAG, "SinchClient started");
if (mListener != null) {
mListener.onStarted();
}
}
#Override
public void onClientStopped(SinchClient client) {
Log.d(TAG, "SinchClient stopped");
}
#Override
public void onLogMessage(int level, String area, String message) {
switch (level) {
case Log.DEBUG:
Log.d(area, message);
break;
case Log.ERROR:
Log.e(area, message);
break;
case Log.INFO:
Log.i(area, message);
break;
case Log.VERBOSE:
Log.v(area, message);
break;
case Log.WARN:
Log.w(area, message);
break;
}
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client,
ClientRegistration clientRegistration) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call call) {
Log.d(TAG, "Incoming call");
Intent intent = new Intent(SinchService.this, Calling.class);
intent.putExtra(CALL_ID, call.getCallId());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
SinchService.this.startActivity(intent);
}
}
}
And the base activity is CallActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.sinch.android.rtc.calling.Call;
import com.squareup.picasso.Picasso;
import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
public class Calling extends CallActivity {
private String calleeID;
private TextView serviceName;
Bundle callDetails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_calling);
callDetails = getIntent().getBundleExtra("callDetails");
//Setup end button
Button endCallButton = findViewById(R.id.endcall);
endCallButton.setOnClickListener(v -> endCall());
}
private void endCall() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
finishActivity(FLAG_ACTIVITY_PREVIOUS_IS_TOP);
finish();
}
// invoked when the connection with SinchServer is established
#Override
protected void onServiceConnected() {
//Setup Calling Screen
ImageView avatar = findViewById(R.id.dialingAvatar);
Picasso.get().load(callDetails.getString("Logo")).into(avatar);
TextView midScreenName = findViewById(R.id.memberName);
midScreenName.setText(callDetails.getString("Name"));
serviceName = findViewById(R.id.serviceName);
serviceName.setText(callDetails.getString("Service"));
TextView ratings = findViewById(R.id.rating);
ratings.setText(callDetails.getString("Rating") + " ★");
//Get CallerID and CalleeID
calleeID = callDetails.getString("CalleeID");
//Start sinch Service
if(!getSinchServiceInterface().isStarted()){
getSinchServiceInterface().startClient(callDetails.getString("CallerID"));
Call call = getSinchServiceInterface().callUserVideo(calleeID);
Intent callServiceScreen = new Intent(this, ServiceCallActivity.class);
callDetails.putString(SinchService.CALL_ID, call.getCallId());
callServiceScreen.putExtra("Call Details", callDetails);
startActivity(callServiceScreen);
}
}
#Override
public void onDestroy() {
if (getSinchServiceInterface() != null) {
getSinchServiceInterface().stopClient();
}
super.onDestroy();
}
}
I have been banging my head against this but I cannot figure out what's wrong. I sure it's something stupid and obvious that I can't see because I am too close to the code. But any ideas you guys have would be very helpful!
It looks like you are not waiting for it to start before you try to make a call. We recommend to start the service when the app starts. If you dont do that you need to wait or the onStarted event in the service for fire
I am using in app billing v3 library, it is always get error
and error code is 101
What does this error code mean?
some details:
I am a developer working from Palestine and working on an app uploadded on Indian google play account
I created activity that included three buttons to purchase remove Ads
-the first button to subscribe one month
-the second to subscribe one year
-the third to purchase lifetime
I used this library 'com.anjlab.android.iab.v3:library:1.0.44'
I created product in google play console and its name PRODUCT_ID
this product will purchased when user click on button lifeTime
and I created two subscriptions
-the first's name is SUBSCRIPTION_MONTH_ID
and will be purchased when the user click on oneMonth button
-the second's name is SUBSCRIPTION_YEAR_ID
and will be purchased when the user click on oneYear button
this the code that I used
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.anjlab.android.iab.v3.BillingProcessor;
import com.anjlab.android.iab.v3.TransactionDetails;
public class InAppBilling extends AppCompatActivity{
BillingProcessor bp;
private static final String PRODUCT_ID = "****";
private static final String SUBSCRIPTION_MONTH_ID = "***";
private static final String SUBSCRIPTION_YEAR_ID = "***";
private static final String LICENSE_KEY = "*****";
private static final String MERCHANT_ID = "**";
Button oneMonth, oneYear, lifeTime;
int flag;
String android_id;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_in_app_purchase);
flag = 0;
android_id = Settings.Secure.getString(getApplicationContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
final Toolbar toolbar = findViewById(R.id.toolbar);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
toolbar.setTitle("Remove Ads");
}
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
if(!BillingProcessor.isIabServiceAvailable(this)) {
Toast.makeText(this, "In-app billing service is unavailable, please upgrade Android Market/Play to version >= 3.9.16", Toast.LENGTH_SHORT).show();
}
bp = new BillingProcessor(this, LICENSE_KEY, MERCHANT_ID, new BillingProcessor.IBillingHandler() {
#Override
public void onProductPurchased(String productId, TransactionDetails details) {
Toast.makeText(InAppBilling.this, "successfully purchased, restart the app please", Toast.LENGTH_SHORT).show();
}
#Override
public void onBillingError(int errorCode, Throwable error) {
Toast.makeText(InAppBilling.this, "Error Billing", Toast.LENGTH_SHORT).show();
Log.e("nourbilling", "onBillingError: errorCode: "+errorCode+" error: "+error);
}
#Override
public void onBillingInitialized() {
}
#Override
public void onPurchaseHistoryRestored() {
for(String sku : bp.listOwnedProducts())
Log.d("nourbilling", "Owned Managed Product: " + sku);
for(String sku : bp.listOwnedSubscriptions())
Log.d("nourbilling", "Owned Subscription: " + sku);
}
});
oneMonth = findViewById(R.id.oneMonth);
oneYear = findViewById(R.id.oneYear);
lifeTime = findViewById(R.id.lifetime);
final Activity activity = this;
oneMonth.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flag = 1;
createDialog(savedInstanceState, activity).show();
}
});
oneYear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flag = 2;
createDialog(savedInstanceState, activity).show();
}
});
lifeTime.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flag = 3;
createDialog(savedInstanceState, activity).show();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (!bp.handleActivityResult(requestCode, resultCode, data))
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onDestroy() {
if (bp != null)
bp.release();
super.onDestroy();
}
public Dialog createDialog(Bundle savedInstanceState, final Activity activity) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("are you sure to remove ads by billing?")
.setPositiveButton("yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (flag == 1) {
bp.subscribe(activity, SUBSCRIPTION_MONTH_ID);
} else if (flag == 2) {
bp.subscribe(activity, SUBSCRIPTION_YEAR_ID);
} else if (flag == 3) {
bp.purchase(activity, PRODUCT_ID);
}
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
return builder.create();
}
}
can you help me, please?
I can't for the life of me get picture to display right after taking it directly from app.
Currently, picture gets saved to gallery, doesn't display, and user has to select from gallery.
Code is below, can someone figure out what I'm doing wrong?
Total Android newbie and have been stuck on this for hours! How can Android not have such a common feature be easier to implement? sigh
package com.tractable.imagegraph_dev.tractableapp;
import android.app.Activity;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.view.View.OnClickListener;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.ScrollView;
import android.widget.Switch;
import android.widget.TextView;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.io.File;
public class MainActivity extends Activity {
private boolean hasActiveNetworkRequest = false;
private static final int SELECT_PICTURE = 0;
private NetworkUtils networkUtils = new NetworkUtils();
private GuiToolbelt guiToolbelt = new GuiToolbelt();
private ImageUploader imageUploader = new ImageUploader();
private ResponseParser responseParser = new ResponseParser();
private ImageUtils imageUtils = new ImageUtils();
private Toolbelt toolbelt = new Toolbelt();
private ImageView imageView;
private Bitmap bitmap;
private Bitmap dispBitmap;
private static double neededRatio = 1024.0 / 768.0;
private Button choosePhotoButton;
private Button takePhotoButton;
private TextView textView;
private String responseText;
private FrameLayout progressOverlay;
private ScrollView switchesScrollView;
private LinearLayout switchesLayout;
// Classifiers
private List<String> classifierNames = new ArrayList<String>();
private List<Switch> switches = new ArrayList<Switch>();
private String currentCategory = "";
private List<RadioButton> categoryButtons = new ArrayList<RadioButton>();
private RadioButton pipeButton;
private RadioButton carInsuranceButton;
private RadioButton dermatologyButton;
private Button runClassifiersButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
switchesLayout = (LinearLayout) findViewById(R.id.SwitchesLayout);
imageView = (ImageView) findViewById(R.id.icon);
choosePhotoButton = (Button) findViewById(R.id.uploadButton);
textView = (TextView) findViewById(R.id.messageText);
takePhotoButton = (Button) findViewById(R.id.takePhotoButton);
progressOverlay = (FrameLayout) findViewById(R.id.overlayFrame);
choosePhotoButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
pickPhoto(imageView);
}
});
takePhotoButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
takePhoto(imageView);
}
});
pipeButton = (RadioButton) findViewById(R.id.pipesRadioButton);
carInsuranceButton = (RadioButton) findViewById(R.id.carInsuranceRadioButton);
dermatologyButton = (RadioButton) findViewById(R.id.dermatologyRadioButton);
categoryButtons.add(pipeButton);
categoryButtons.add(carInsuranceButton);
categoryButtons.add(dermatologyButton);
runClassifiersButton = (Button) findViewById(R.id.runClassifiersButton);
pipeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (!hasActiveNetworkRequest) {
hasActiveNetworkRequest = true;
setupUiForCategory("pipes");
setImageUploadedText("");
pipeButton.setChecked(true);
}
}
});
carInsuranceButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (!hasActiveNetworkRequest) {
hasActiveNetworkRequest = true;
setupUiForCategory("cars");
setImageUploadedText("");
carInsuranceButton.setChecked(true);
}
}
});
dermatologyButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
clearClassificationData();
setImageUploadedText("Classifier not available (currently training)");
}
});
runClassifiersButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
if (!hasActiveNetworkRequest) {
if (guiToolbelt.hasSelectedSwitch(switches)) {
progressOverlay.setVisibility(View.VISIBLE);
takePhotoButton.setEnabled(false);
choosePhotoButton.setEnabled(false);
uploadPhoto(imageView);
} else {
setImageUploadedText("Please select at least one classifer");
}
}
}
});
}
public void pickPhoto(View view) {
if (!currentCategory.equals("")) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
} else if (currentCategory.equals("")) {
setImageUploadedText("Please select a category");
}
}
public void takePhoto(View view) {
if (!currentCategory.equals("")) {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent.createChooser(intent, "Take Picture"), 0);
} else if (currentCategory.equals("")) {
setImageUploadedText("Please select a category");
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK)
if (networkUtils.isNetworkConnected(this.getApplicationContext())) {
try {
try {
Uri s1 = data.getData();
System.out.println("-+-+-1" + s1 + "-" + data);
InputStream s2 = getContentResolver().openInputStream(s1);
System.out.println("-+-+-2");
bitmap = BitmapFactory.decodeStream(s2);
System.out.println("-+-+-try" + bitmap.getWidth() + " " + bitmap.getHeight());
} catch (Exception e) {
e.printStackTrace();
bitmap = (Bitmap) data.getExtras().get("data");
System.out.println("-+-+-catch" + bitmap.getWidth() + " " + bitmap.getHeight());
}
int neededHeight = bitmap.getHeight();
if (bitmap.getHeight() > bitmap.getWidth())
neededHeight = (int) (bitmap.getWidth() / neededRatio);
int neededWidth = (int) (neededHeight * neededRatio);
// Setup Image Data
bitmap = ThumbnailUtils.extractThumbnail(bitmap, neededWidth, neededHeight);
//dispBitmap = Bitmap.createBitmap(bitmap);
//if (dispBitmap.getWidth() < dispBitmap.getHeight()) {
// dispBitmap = imageUtils.rotateImage(dispBitmap);
//}
//if (dispBitmap.getWidth() > Constants.scaledImagePixels || dispBitmap.getHeight() > Constants.scaledImagePixels) {
// dispBitmap = imageUtils.scaleImageWidth(dispBitmap, Constants.scaledImagePixels);
//} else if (dispBitmap.getHeight() < Constants.minimumImagePixels || dispBitmap.getWidth() < Constants.minimumImagePixels) {
// dispBitmap = imageUtils.scaleImageWidth(dispBitmap, Constants.scaledImagePixels);
//}
imageView.setImageBitmap(bitmap);
runClassifiersButton.setEnabled(true);
} catch (Exception e) {
e.printStackTrace();
setImageUploadedText("There was an error getting the image");
}
} else {
setImageUploadedText("Please connect to the internet to use the app.");
progressOverlay.setVisibility(View.GONE);
}
}
public void uploadPhoto(View view) {
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
processImageUpload();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
textView.setText("Uploading...");
}
public void setupUiForCategory(final String category) {
clearClassificationData();
setCurrentCategory(category);
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
classifierNames = ClassifierDelegate.getInstance().getClassifersListForCategory(category);
runOnUiThread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < classifierNames.size(); i++) {
Switch newSwitch = new Switch(getBaseContext());
newSwitch.setText(classifierNames.get(i));
switches.add(newSwitch);
switchesLayout.addView(newSwitch);
}
guiToolbelt.setSwitchAsSelectedByString(switches, pipeButton.getText().toString());
hasActiveNetworkRequest = false;
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
private void clearClassificationData() {
setCurrentCategory("");
classifierNames.clear();
guiToolbelt.setAllRadioButtions(categoryButtons, false);
for (int i = 0; i < switches.size(); i++) {
switches.get(i).setText("");
}
switches.clear();
switchesLayout.removeAllViewsInLayout();
}
public void processImageUpload() throws Exception {
responseText = imageUploader.uploadImage(Constants.serverUrl, bitmap, getClassifiersList(), currentCategory);
if (responseText != "") {
// Map<String, Double> parsedResponse = responseParser.parseMapResponse(response);
this.runOnUiThread(new Runnable() {
#Override
public void run() {
setImageUploadedText(responseText.replace(";", "\n"));
progressOverlay.setVisibility(View.GONE);
takePhotoButton.setEnabled(true);
choosePhotoButton.setEnabled(true);
}
});
}
}
private List getClassifiersList() {
List<String> classifiersList = new ArrayList<String>();
for (int i = 0; i < switches.size(); i++) {
if (switches.get(i).isChecked()) {
classifiersList.add(switches.get(i).getText().toString().toLowerCase().replace(" ", ""));
}
}
return classifiersList;
}
void setImageUploadedText(String text) {
textView.setText(text);
}
void setCurrentCategory(String catergory) { currentCategory = catergory; }
}
By the way, I am writing this app strictly for a Moto 4G.
public static final int CAMERA_REQUEST = 1980;
Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intentcamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intentcamera, CAMERA_REQUEST);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST)
{
Bitmap photo = (Bitmap) data.getExtras().get("data");
your_screenview.setImageBitmap(photo);
ProgressDialog quits updating when orientation of screen changes. I have put into place a fix that salvages the asynctask and sets the activity of the asynctask to the new activity after it is destroyed and rebuilt. The percentage complete on the progressdialog stays at the percentage it was at before the orientation change.
What am I missing?
package net.daleroy.fungifieldguide.activities;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Toast;
import net.daleroy.fungifieldguide.R;
import net.daleroy.fungifieldguide.fungifieldguideapplication;
public class FungiFieldGuide extends Activity {
//static final int PROGRESS_DIALOG = 0;
//ProgressThread progressThread;
private final static String LOG_TAG = FungiFieldGuide.class.getSimpleName();
fungifieldguideapplication appState;
private DownloadFile mTask;
public boolean mShownDialog;
ProgressDialog progressDialog;
private final static int DIALOG_ID = 1;
#Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
if ( id == DIALOG_ID ) {
mShownDialog = true;
}
}
private void onTaskCompleted() {
Log.i(LOG_TAG, "Activity " + this + " has been notified the task is complete.");
//Check added because dismissDialog throws an exception if the current
//activity hasn't shown it. This Happens if task finishes early enough
//before an orientation change that the dialog is already gone when
//the previous activity bundles up the dialogs to reshow.
if ( mShownDialog ) {
dismissDialog(DIALOG_ID);
Toast.makeText(this, "Finished..", Toast.LENGTH_LONG).show();
}
}
#Override
protected Dialog onCreateDialog(int id) {
switch(id) {
case DIALOG_ID:
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading Database (only first run)...");
return progressDialog;
default:
return super.onCreateDialog(id);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
appState = ((fungifieldguideapplication)this.getApplication());
Object retained = getLastNonConfigurationInstance();
if ( retained instanceof DownloadFile ) {
Log.i(LOG_TAG, "Reclaiming previous background task.");
mTask = (DownloadFile) retained;
mTask.setActivity(this);
//showDialog(DIALOG_ID);
}
else {
if(!appState.service.createDataBase())
{
Log.i(LOG_TAG, "Creating new background task.");
//showDialog(DIALOG_ID);
mTask = new DownloadFile(this);
mTask.execute("http://www.codemarshall.com/Home/Download");
}
}
//showDialog(PROGRESS_DIALOG);
View btn_Catalog = findViewById(R.id.btn_Catalog);
btn_Catalog.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Intent i = new Intent(getBaseContext(), Cat_Genus.class);//new Intent(this, Total.class);
startActivity(i);
}
});
View btn_Search = findViewById(R.id.btn_Search);
btn_Search.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Intent i = new Intent(getBaseContext(), Search.class);//new Intent(this, Total.class);
startActivity(i);
}
});
}
#Override
public Object onRetainNonConfigurationInstance() {
mTask.setActivity(null);
return mTask;
}
#Override
public void onDestroy()
{
super.onDestroy();
//progressDialog.dismiss();
//progressDialog = null;
appState.service.ClearSearchParameters();
}
private class DownloadFile extends AsyncTask<String, Integer, Boolean>{
private FungiFieldGuide activity;
private boolean completed;
private String Error = null;
private String Content;
private DownloadFile(FungiFieldGuide activity) {
this.activity = activity;
}
#Override
protected void onPreExecute()
{
showDialog(DIALOG_ID);
}
#Override
protected Boolean doInBackground(String... urlarg) {
int count;
try {
URL url = new URL(urlarg[0]);
URLConnection conexion = url.openConnection();
conexion.setDoInput(true);
conexion.setUseCaches(false);
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// downlod the file
InputStream input = new BufferedInputStream(conexion.getInputStream());
OutputStream output = new FileOutputStream("/data/data/net.daleroy.fungifieldguide/databases/Mushrooms.db");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int)total*100/lenghtOfFile);
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
Log.i(LOG_TAG, e.getMessage());
}
return null;
}
#Override
public void onProgressUpdate(Integer... args){
progressDialog.setProgress(args[0]);
}
#Override
protected void onPostExecute(Boolean result)
{
completed = true;
notifyActivityTaskCompleted();
}
private void notifyActivityTaskCompleted() {
if ( null != activity ) {
activity.onTaskCompleted();
}
}
private void setActivity(FungiFieldGuide activity) {
this.activity = activity;
if ( completed ) {
notifyActivityTaskCompleted();
}
}
}
}
This is not a real solution but to prevent this I just disabled orientation changes during the life of the AsyncTask with adding first:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
and when the job is done:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
Hope this helps.