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);
Related
This bug is only on some devices.
Project scope:
Indoor navigation system used in malls/ships to locate shops.
It uses beacons to locate shops with bluetooth connection. It uses camera to show directions (arrow) image overlays.
In ArCameraActivity, half green screen shows up in camera preview.
code:
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.opengl.Matrix;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import dagger.android.support.DaggerAppCompatActivity;
public class ARActivity extends DaggerAppCompatActivity implements SensorEventListener, LocationListener,
ActivityCompat.OnRequestPermissionsResultCallback, ARView {
private static boolean IS_NAVIGATION_CLICKED = false;
#Inject
ARPresenter presenter;
#BindView(R.id.img_clear)
ImageView imgClear;
#BindView(R.id.img_logout)
ImageView imgLogout;
#BindView(R.id.img_map)
ImageView imgMap;
#BindView(R.id.img_navigation)
ImageView imgNavigation;
final static String TAG = "ARActivity";
private SurfaceView surfaceView;
private FrameLayout cameraContainerLayout;
private AROverlayView arOverlayView;
private Camera camera;
private ARCamera arCamera;
private TextView tvCurrentLocation;
private SensorManager sensorManager;
private final static int REQUEST_CAMERA_PERMISSIONS_CODE = 11;
public static final int REQUEST_LOCATION_PERMISSIONS_CODE = 0;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10 meters
private static final long MIN_TIME_BW_UPDATES = 0;//1000 * 60 * 1; // 1 minute
private LocationManager locationManager;
public Location location;
boolean isGPSEnabled;
boolean isNetworkEnabled;
boolean locationServiceAvailable;
private ScanRegionsService scanRegionsService;
private boolean isBeaconLoaded = false;
// private static GetMallResponse.Data.Mall identifiedMall;
private Dialog dialog = null;
private static final String IMAGE_URL = "http://98.156.231.92/maps/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ar);
ButterKnife.bind(this);
sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
cameraContainerLayout = (FrameLayout) findViewById(R.id.camera_container_layout);
surfaceView = (SurfaceView) findViewById(R.id.surface_view);
tvCurrentLocation = (TextView) findViewById(R.id.tv_current_location);
arOverlayView = new AROverlayView(this);
scanRegionsService = new ScanRegionsService(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
beginService();
}
}
if (Util.getSelectedShop() != null) {
showLoading();
}
}
private Runnable mRunnable = new Runnable() {
#Override
public void run() {
if (!isBeaconLoaded) {
Log.d(TAG, "run: "+ isBeaconLoaded);
dismissLoading();
if(!isFinishing()) {
new AlertDialog.Builder(ARActivity.this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("There is no beacon in your surroundings")
.setMessage("Are you sure you want to stop navigation?")
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Util.setSelectedShop(null);
finish();
}
})
.show();
}
}
}
};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
for (int i = 0; i < permissions.length; i++) {
if (permissions[i].equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION) &&
grantResults[i] == PackageManager.PERMISSION_GRANTED) {
beginService();
} else if (permissions[i].equalsIgnoreCase(Manifest.permission.CAMERA) &&
grantResults[i] == PackageManager.PERMISSION_DENIED) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
}
private void beginService() {
isBeaconLoaded = false;
arOverlayView.registerReceiver();
scanRegionsService.setupSpaces();
scanRegionsService.startScanning();
onMallIdentified(Util.getSelectedMall());
new Handler().postDelayed(mRunnable, 10000);
}
#OnClick(R.id.img_map)
public void onMapClicked() {
arOverlayView.unregisterReceiver();
// Util.getRouteMap().clear();
Util.setSelectedShop(null);
// Intent intent = new Intent(this, MainActivity.class);
// startActivity(intent);
finish();
}
#OnClick(R.id.img_navigation)
public void onNavClicked() {
if (!IS_NAVIGATION_CLICKED) {
IS_NAVIGATION_CLICKED = true;
arOverlayView.showNavigationMap();
imgNavigation.setImageDrawable(getResources().getDrawable(R.drawable.navigation_on));
} else {
IS_NAVIGATION_CLICKED = false;
arOverlayView.hideNavigationMap();
imgNavigation.setImageDrawable(getResources().getDrawable(R.drawable.navigation_off));
}
}
#OnClick(R.id.img_logout)
public void onLogoutClicked() {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Confirm")
.setMessage("Are you sure you want to logout?")
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Util.set("authToken", "");
Intent intent = new Intent(ARActivity.this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
})
.setNegativeButton("No", null)
.show();
}
#Override
public void onBackPressed() {
if(!((Activity) this).isFinishing()) {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Confirm")
.setMessage("Are you sure you want to exit the screen?")
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton("No", null)
.show();
}
}
#Override
public void onResume() {
super.onResume();
requestLocationPermission();
requestCameraPermission();
registerSensors();
initAROverlayView();
IntentFilter intentFilter = new IntentFilter(ForegroundScanService.ACTION_DEVICE_DISCOVERED);
registerReceiver(scanningBroadcastReceiver, intentFilter);
}
public void showClearMap() {
imgClear.setVisibility(View.VISIBLE);
}
public void hideClearMap() {
imgClear.setVisibility(View.GONE);
}
#OnClick(R.id.img_clear)
public void onClearClicked() {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Confirm")
.setMessage("Are you sure you want to stop navigation?")
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Util.setSelectedShop(null);
}
})
.setNegativeButton("No", null)
.show();
}
#Override
public void onPause() {
unregisterReceiver(scanningBroadcastReceiver);
releaseCamera();
super.onPause();
}
public void requestCameraPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
this.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSIONS_CODE);
} else {
initARCameraView();
}
}
public void requestLocationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSIONS_CODE);
} else {
initLocationService();
}
}
public void initAROverlayView() {
if (arOverlayView.getParent() != null) {
((ViewGroup) arOverlayView.getParent()).removeView(arOverlayView);
}
cameraContainerLayout.addView(arOverlayView);
}
public void initARCameraView() {
reloadSurfaceView();
if (arCamera == null) {
arCamera = new ARCamera(this, surfaceView);
}
if (arCamera.getParent() != null) {
((ViewGroup) arCamera.getParent()).removeView(arCamera);
}
cameraContainerLayout.addView(arCamera);
arCamera.setKeepScreenOn(true);
initCamera();
}
private void initCamera() {
int numCams = Camera.getNumberOfCameras();
if (numCams > 0) {
try {
camera = Camera.open();
camera.startPreview();
arCamera.setCamera(camera);
} catch (RuntimeException ex) {
Toast.makeText(this, "Camera not found", Toast.LENGTH_LONG).show();
}
}
}
private void reloadSurfaceView() {
if (surfaceView.getParent() != null) {
((ViewGroup) surfaceView.getParent()).removeView(surfaceView);
}
cameraContainerLayout.addView(surfaceView);
}
private void releaseCamera() {
if (camera != null) {
camera.setPreviewCallback(null);
camera.stopPreview();
arCamera.setCamera(null);
camera.release();
camera = null;
}
}
private void registerSensors() {
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
SensorManager.SENSOR_DELAY_FASTEST);
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
float[] rotationMatrixFromVector = new float[16];
float[] projectionMatrix = new float[16];
float[] rotatedProjectionMatrix = new float[16];
SensorManager.getRotationMatrixFromVector(rotationMatrixFromVector, sensorEvent.values);
if (arCamera != null) {
projectionMatrix = arCamera.getProjectionMatrix();
}
Matrix.multiplyMM(rotatedProjectionMatrix, 0, projectionMatrix, 0, rotationMatrixFromVector, 0);
this.arOverlayView.updateRotatedProjectionMatrix(rotatedProjectionMatrix);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
//do nothing
}
private void initLocationService() {
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
this.locationManager = (LocationManager) this.getSystemService(this.LOCATION_SERVICE);
// Get GPS and network status
this.isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
this.isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isNetworkEnabled && !isGPSEnabled) {
// cannot get location
this.locationServiceAvailable = false;
}
this.locationServiceAvailable = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
updateLatestLocation();
}
}
if (isGPSEnabled) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
updateLatestLocation();
}
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}
private void updateLatestLocation() {
if (arOverlayView != null && location != null) {
arOverlayView.updateCurrentLocation(location);
tvCurrentLocation.setText(String.format("lat: %s \nlon: %s \naltitude: %s \n",
location.getLatitude(), location.getLongitude(), location.getAltitude()));
}
}
#Override
public void onLocationChanged(Location location) {
updateLatestLocation();
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
private final BroadcastReceiver scanningBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: ");
isBeaconLoaded = true;
String shopname=Util.getSelectedShop().getShopImage();
Toast.makeText(context, "You are in "+shopname, Toast.LENGTH_LONG).show();
int devicesCount = intent.getIntExtra(BackgroundScanService.EXTRA_DEVICES_COUNT, 0);
RemoteBluetoothDevice device = intent.getParcelableExtra(BackgroundScanService.EXTRA_DEVICE);
Log.i("BEACON", String.format("Total discovered devices: %d\n\nLast scanned device:\n%s", devicesCount, device.toString()));
// statusText.setText(String.format("Total discovered devices: %d\n\nLast scanned device:\n%s", devicesCount, device.toString()));
}
};
#Override
public void onMallIdentified(GetMallResponse.Data.Mall mall) {
// identifiedMall = mall;
// Toast.makeText(this, "Identified "+mall.getPropertyName(), Toast.LENGTH_LONG).show();
presenter.loadShops(mall.getId());
presenter.loadRouteBeacons(mall.getId());
}
public void onUnkownPlaceIdentified() {
arOverlayView.registerReceiver();
Toast.makeText(this, "Unknown place identified", Toast.LENGTH_LONG).show();
List<GetRouteBeaconsResponse.Data.Route> floorRoute = new ArrayList<>();
}
#Override
public void onShopLoaded(List<GetShopsResponse.Data.Shop> shops) {
Log.i(TAG, "onShopLoaded");
if (shops.size() > 0) {
Util.shopMap.clear();
Log.i(TAG, "onShopLoaded shops.size " + shops.size());
Util.activeDeviceMap.clear();
for (GetShopsResponse.Data.Shop shop : shops) {
Util.shopMap.put("" + shop.getId(), shop);
if (shop.getAdImage().length() > 0) {
Drawable drbl = Util.promoImageMap.get(IMAGE_URL + shop.getAdImage());
if (drbl == null) {
String imgkey = IMAGE_URL + shop.getAdImage();
drbl = getResources().getDrawable(R.drawable.promo1, null);
Util.promoImageMap.put(imgkey, drbl);
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Drawable drb2 = drawableFromUrl(imgkey);
Util.promoImageMap.put(IMAGE_URL + shop.getAdImage(), drb2);
} catch (Exception e) {
Log.i(TAG, "Unable to download image");
}
}
};
new Thread(runnable).start();
}
}
}
}
}
#Override
public void onRouteBeaconLoaded(List<GetRouteBeaconsResponse.Data.Route> floors) {
Log.d(TAG, "onRouteBeaconLoaded: ");
Log.i(TAG, "onRouteBeaconLoaded");
// if (floors.size()>0 && Util.getSelectedShop()!=null){
// Log.i(TAG, "onRouteBeaconLoaded floors.size "+floors.size());
// Util.getRouteMap().clear();
// for (GetRouteBeaconsResponse.Data.Route route: floors){
// String comkey = route.proximityUUID+route.major+route.minor;
// Util.getRouteMap().put(comkey, route);
// }
// Util.setSelectedShop(Util.getSelectedShop());
// Log.i(TAG, "onShopLoaded setup space scanRegionsService");
// scanRegionsService.setupSpaces();
// Log.i(TAG, "onShopLoaded startScanning");
// scanRegionsService.startScanning();
// }
if (floors.size() > 0) {
Log.i(TAG, "onRouteBeaconLoaded floors.size " + floors.size());
Util.getRouteMap().clear();
for (GetRouteBeaconsResponse.Data.Route route : floors) {
String comkey = route.proximityUUID + route.major + route.minor;
Util.getRouteMap().put(comkey, route);
}
Log.i(TAG, "onShopLoaded setup space scanRegionsService");
scanRegionsService.setupSpaces();
Log.i(TAG, "onShopLoaded startScanning");
scanRegionsService.startScanning();
}
arOverlayView.registerReceiver();
}
public static Drawable drawableFromUrl(String url) throws IOException {
Bitmap x;
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.connect();
InputStream input = connection.getInputStream();
x = BitmapFactory.decodeStream(input);
return new BitmapDrawable(x);
}
private void initLoadingDialog() {
dialog = new Dialog(this);
dialog.setCancelable(false);
dialog.setContentView(R.layout.show_loading);
TextView txtFind = dialog.findViewById(R.id.findingBeacons);
txtFind.setVisibility(View.VISIBLE);
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
#Override
public boolean onKey(DialogInterface arg0, int keyCode,
KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
dialog.dismiss();
}
return true;
}
});
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
}
public void showLoading() {
try {
if (dialog != null) {
dialog.show();
} else {
initLoadingDialog();
dialog.show();
}
} catch (Exception e) {
}
}
public void dismissLoading() {
try {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
} catch (Exception e) {
}
}
}
green screen
Getting like this for camera activity in redmi y2 phone only. Its works well on other models. What might be issue? It shows directions in camera to shop using beacon device. Android os version is not problem.
white screen on some devices - samsung tab, oneplus 7, BLU G9 Pro phone
white screen
this activity shows navigation with help of beacons in camera shows overlay of imageview. it works on some devices, i have tried various methods to resolve it,
doesn't work. added latest camera v2 api.
How can i resolve this issue? thanks in advance.
Sometimes this "green screen" issue is caused by the camera's preview resolution. Try to get supported preview size from camera instance.
mParams = mCamera.getParameters();
List<Camera.Size> supportedPreviewSizes = mParams.getSupportedPreviewSizes();
Camera.Size bestPreviewSize = supportedPreviewSizes.get(0);
for (Camera.Size sz : supportedPreviewSizes) {
/* perfect match */
if(sz.width == mWidth && sz.height == mHeight) {
bestPreviewSize = sz;
break;
} else {
int bestArea = bestPreviewSize.width*bestPreviewSize.height;
int currArea = sz.width*sz.height;
int targetArea = mWidth*mHeight;
if (Math.abs(currArea-targetArea) < Math.abs(bestArea-targetArea)) {
bestPreviewSize = sz;
}
}
}
mCurrWidth = bestPreviewSize.width;
mCurrHeight = bestPreviewSize.height;
mParams.setPreviewSize(mCurrWidth, mCurrHeight);
/* Set preview format */
mParams.setPreviewFormat(ImageFormat.NV21);
/* Apply Parameters */
mCamera.setParameters(mParams);
mCamera.startPreview();
You can also try to force some fixed resolution depending on some device conditions, like display width, for example. Some resolutions i found useful on my use case:
width = 1280;
heigth = 720;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowMetrics windowMetrics = getWindowManager().getCurrentWindowMetrics();
if (isPortrait) {
if (windowMetrics.getBounds().width() <= 720) {
width = 720;
heigth = 480;
}
} else {
if (windowMetrics.getBounds().width() <= 1344) {
width = 960;
heigth = 540;
}
}
} else {
if (isPortrait) {
if (getDisplay().getWidth() <= 720) {
width = 720;
heigth = 480;
}
} else {
if (getDisplay().getWidth() <= 1344) {
width = 960;
heigth = 540;
}
}
}
Keep in mind that the best solution for me was getting the supported sizes to calculate the best preview size.
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
This is my code I have got repeat one working but I want to be able to repeat all songs so it does not stop playing the music, I also want to be able to repeat one single song. I have tried to find documentation to help me but I haven't found anything. Any help would be appreciated
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import static android.R.drawable.ic_media_play;
public class MainActivity extends Activity {
private static final int UPDATE_FREQUENCY = 500;
private static final int STEP_VALUE = 5000;
private static final int CALL = 872;
static MediaPlayer mp = null;
private final Handler handler = new Handler();
private TextView selectedFile;
private TextView selectedArtist;
private RecyclerView recyclerView;
private SeekBar seekbar;
private MediaPlayer player;
private ImageButton playButton;
private ImageButton prevButton;
private ImageButton nextButton;
private ImageButton repeatButton;
private ImageButton shuffleButton;
private boolean isStarted = true;
private int currentPosition;
private boolean isMovingSeekBar = false;
private MyRecyclerViewAdapter adapter;
private final Runnable updatePositionRunnable = new Runnable() {
public void run() {
updatePosition();
}
};
private List<Music> musicList;
private boolean isShuffle = false;
private boolean isRepeat = false;
private View.OnClickListener onButtonClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play:
if (player.isPlaying()) {
handler.removeCallbacks(updatePositionRunnable);
player.pause();
playButton.setImageResource(android.R.drawable.ic_media_play);
} else {
if (isStarted) {
player.start();
playButton.setImageResource(android.R.drawable.ic_media_pause);
updatePosition();
} else {
startPlay(currentPosition);
}
}
break;
case R.id.prev:
startPlay(currentPosition - 1);
break;
case R.id.next:
startPlay(currentPosition + 1);
break;
case R.id.shuffle:
if (isShuffle) {
Collections.shuffle(musicList);
adapter.notifyDataSetChanged();
shuffleButton.setColorFilter(-16776961);
} else {
sortMusicList();
shuffleButton.setColorFilter(-16777216);
}
isShuffle = !isShuffle;
break;
case R.id.repeat: {
if (isRepeat) {
player.setLooping(true);
repeatButton.setImageResource(R.drawable.ic_repeat_black_24dp);
repeatButton.setColorFilter(-16776961);
} else {
player.setLooping(false);
repeatButton.setColorFilter(-16777216);
}
break;
}
}
}
};
private void sortMusicList() {
Collections.sort(musicList, new Comparator<Music>() {
#Override
public int compare(Music o1, Music o2) {
return o1.getArtists().compareTo(o2.getArtists());
}
});
if (adapter != null) {
adapter.notifyDataSetChanged();
}
}
private MediaPlayer.OnCompletionListener onCompletion = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
stopPlay();
startPlay(currentPosition + 1);
}
};
private MediaPlayer.OnErrorListener onError = new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
};
private SeekBar.OnSeekBarChangeListener seekBarChanged = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
isMovingSeekBar = false;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
isMovingSeekBar = true;
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (isMovingSeekBar) {
player.seekTo(progress);
Log.i("OnSeekBarChangeListener", "onProgressChanged");
} else {
TextView duration = findViewById(R.id.song_duration);
duration.setText(String.valueOf(progress));
long totalSeconds = TimeUnit.MILLISECONDS.toSeconds(progress);
long minss = totalSeconds / 60;
long seconds = totalSeconds % 60;
duration.setText(String.format(Locale.UK, "%02d:%02d", minss, seconds));
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
recyclerView = findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
int permissionCheck = ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
setupUI();
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
CALL);
}
}
#Override
protected void onPause() {
super.onPause();
player.getCurrentPosition();
}
private void setupUI() {
selectedFile = findViewById(R.id.selected_file);
selectedArtist = findViewById(R.id.artists);
seekbar = findViewById(R.id.seekbar);
prevButton = findViewById(R.id.prev);
playButton = findViewById(R.id.play);
nextButton = findViewById(R.id.next);
repeatButton = findViewById(R.id.repeat);
shuffleButton = findViewById(R.id.shuffle);
player = new MediaPlayer();
player.setOnCompletionListener(onCompletion);
player.setOnErrorListener(onError);
seekbar.setOnSeekBarChangeListener(seekBarChanged);
musicList = new MusicManager().getMusic(getContentResolver());
sortMusicList();
adapter = new MyRecyclerViewAdapter(musicList);
adapter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
startPlay(position);
}
});
recyclerView.setAdapter(adapter);
prevButton.setOnClickListener(onButtonClick);
playButton.setOnClickListener(onButtonClick);
nextButton.setOnClickListener(onButtonClick);
shuffleButton.setOnClickListener(onButtonClick);
repeatButton.setOnClickListener(onButtonClick);
}
#Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(updatePositionRunnable);
player.stop();
player.reset();
player.release();
player = null;
}
private void startPlay(int position) {
if (position < 0) {
position = 0;
}
if (position >= musicList.size()) {
position = musicList.size() - 1;
}
String file = musicList.get(position).getFile();
String title = musicList.get(position).getTitle();
String artists = musicList.get(position).getArtists();
currentPosition = position;
if (artists != null) {
selectedArtist.setText(artists);
}
if (title != null) {
selectedFile.setText(title);
}
seekbar.setProgress(0);
updatePosition();
player.stop();
player.reset();
try {
player.setDataSource(file);
player.prepare();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
seekbar.setMax(player.getDuration());
playButton.setImageResource(android.R.drawable.ic_media_pause);
isStarted = true;
}
private void stopPlay() {
player.stop();
player.reset();
playButton.setImageResource(ic_media_play);
handler.removeCallbacks(updatePositionRunnable);
isStarted = false;
}
private void updatePosition() {
handler.removeCallbacks(updatePositionRunnable);
seekbar.setProgress(player.getCurrentPosition());
handler.postDelayed(updatePositionRunnable, UPDATE_FREQUENCY);
if (adapter == null) {
return;
}
}
}
this is just the main activity if you need anything else just ask.
To play a list of songs loop continuously, you can define a variable to be used as an index of the number of songs completed. After completion of the of the list, replay the list of songs by calling the index again. An example of this is:
int[] myAudio = {R.raw.audio1, R.raw.audio2, R.raw.audio3};
int mSongFinish = 0;
MediaPlayer mp = MediaPlayer.create(this, myAudio[0]);
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mSongFinish++;
mp.reset();
if (mSongFinish < myAudio.length()) {
try {
AssetFileDescriptor asset = getResources().openRawResourceFd(myAudio[mSongFinish]);
if (asset != null) {
mp.setDataSource(afd.getFileDescriptor(), asset.getStartOffset(), asset.getLength());
asset.close();
mp.prepare();
}
} catch (Exception ex) {
// report a crash
}
} else {
mSongFinish=0;
mp.release();
mp = null; // either set counter to 0 and start again or call end of list
}
}
});
mp.start();
To do this on a button click, just use an onClickListener. To loop a single song on button click, use mp.setLooping(true).
Ok,
I'm doing this for 4 straight hours. And the facebook Login still doesn't work. The session state is always OPENING. ALWAYS. onActivityResult NEVER gets called. The key in the developer console is correct, the starting class is correct, and this is my code
package XXXXX
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import ua.org.zasadnyy.zvalidations.Field;
import ua.org.zasadnyy.zvalidations.Form;
import ua.org.zasadnyy.zvalidations.validations.HasMinimumLength;
import ua.org.zasadnyy.zvalidations.validations.IsEmail;
import ua.org.zasadnyy.zvalidations.validations.NotEmpty;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Base64;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphUser;
import com.facebook.widget.LoginButton;
public class SplashScreen extends FragmentActivity {
public static String TAG = "SplashScreen";
/**
* LoginActivity
*/
private static final int LOGIN = 0;
private static final int SIGNUP = 1;
private static final int SELECTUSERNAME = 2;
private static final int FRAGMENT_COUNT = SELECTUSERNAME +1;
private boolean isResumed = false;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
private MenuItem settings;
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback =
new Session.StatusCallback() {
#Override
public void call(Session session,
SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
/**
* UI Elements
*/
Button btn_signUp;
Button btn_signUpSubmit;
LoginButton btn_facebookAuth;
//Edit Text
EditText edittextEmail;
EditText edittextPassword;
//Form
Form signUpForm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate");
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
setContentView(R.layout.splash);
FragmentManager fm = getSupportFragmentManager();
fragments[LOGIN] = fm.findFragmentById(R.id.loginFragment);
fragments[SIGNUP] = fm.findFragmentById(R.id.signUpFragment);
fragments[SELECTUSERNAME] = fm.findFragmentById(R.id.selectUserNameFragment);
FragmentTransaction transaction = fm.beginTransaction();
for(int i = 0; i < fragments.length; i++) {
transaction.hide(fragments[i]);
}
transaction.commit();
btn_signUp = ( Button ) findViewById(R.id.btn_signUpMail);
btn_signUp.setOnClickListener( listener_btn_signUp );
btn_signUpSubmit = (Button) findViewById(R.id.btn_signUpSubmit);
btn_signUpSubmit.setOnClickListener(listener_btn_signUpSubmit);
edittextEmail = (EditText)findViewById(R.id.et_signUpMail);
edittextPassword = (EditText)findViewById(R.id.et_signUpPw);
signUpForm = new Form ( this );
signUpForm.addField(Field.using(edittextEmail).validate(NotEmpty.build(this.getApplicationContext())).validate(IsEmail.build(this.getApplicationContext())));
signUpForm.addField(Field.using(edittextPassword).validate(NotEmpty.build(this.getApplicationContext())).validate(HasMinimumLength.build(this.getApplicationContext(), 8)));
btn_facebookAuth = (LoginButton)findViewById(R.id.login_button);
btn_facebookAuth.setReadPermissions(Arrays.asList("email"));
}
private OnClickListener listener_btn_signUp = new OnClickListener() {
#Override
public void onClick(View v) {
showFragment(SIGNUP, true);
}
};
private OnClickListener listener_btn_signUpSubmit = new OnClickListener() {
#Override
public void onClick(View v) {
if (signUpForm.isValid()) {
Log.i("SignupFragment", "Form is valid");
// User userModel = new User();
// userModel.isFacebookConnected = "0";
// userModel.userEmail = edittextEmail.getText().toString();
// userModel.userPassword = edittextPassword.getText().toString();
// SelectUserNameFragment selectUserNameFragment = new SelectUserNameFragment();
// SelectUserNameFragment.user = userModel;
// getFragmentManager()
// .beginTransaction()
// .replace(android.R.id.content, selectUserNameFragment)
// .addToBackStack("")
// .commit();
} else {
Log.i("SignupFragment", "Form not valid");
}
}
};
private void showFragment(int fragmentIndex, boolean addToBackStack) {
Log.i(TAG, "showFragment");
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
for (int i = 0; i < fragments.length; i++) {
if (i == fragmentIndex) {
transaction.show(fragments[i]);
} else {
transaction.hide(fragments[i]);
}
}
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
Log.i(TAG, "onSessionStateChange");
FragmentManager manager = getSupportFragmentManager();
int backStackSize = manager.getBackStackEntryCount();
for (int i = 0; i < backStackSize; i++) {
manager.popBackStack();
}
System.out.println ( state.name() );
if (state.isOpened()) {
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
try {
User userModel = new User();
userModel.facebookId = user.getId();
Map<String, String> where = new HashMap<String, String>();
where.put("where", "WHERE facebookId='" + user.getId() + "'" );
userModel.loadModelFrom(where);
if ( userModel.userData.isEmpty() ) {
userModel.isFacebookConnected = "1";
userModel.userEmail = user.asMap().get("email").toString();
SelectUserNameFragment.user = userModel;
showFragment(SELECTUSERNAME, true);
} else {
Intent intent = new Intent ( getApplicationContext(), DashboardActivity.class );
intent.putExtra("User", userModel);
startActivity(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).executeAsync();
// showFragment(DASHBOARD, false);
} else if (state.isClosed()) {
showFragment(LOGIN, false);
}
}
#Override
protected void onResumeFragments() {
super.onResumeFragments();
Log.i(TAG, "onResumeFragments");
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
Intent intent = new Intent ( this, DashboardActivity.class );
intent.putExtra("Session", session);
startActivity(intent);
} else {
showFragment(LOGIN, false);
}
}
#Override
public void onResume() {
super.onResume();
Log.i(TAG, "onResume");
uiHelper.onResume();
isResumed = true;
}
#Override
public void onPause() {
super.onPause();
Log.i(TAG, "onPause");
uiHelper.onPause();
isResumed = false;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "onActivityResult");
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
uiHelper.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(TAG, "onSaveInstanceState");
uiHelper.onSaveInstanceState(outState);
}
}
What did I forget?
Apparently it is not allowed to have
android:noHistory="true" in your manifest. I removed it and now it works.
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.