I am trying to send the selected image the user selected from their Google Drive to another function. I would like retrieve the content the user selected and send the photo uri or a bitmap of that photo to a function. Can anyone help me out?
This is my code:
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveFolder;
import com.google.android.gms.drive.DriveId;
import com.google.android.gms.drive.MetadataChangeSet;
import com.google.android.gms.drive.OpenFileActivityBuilder;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "Google Drive Activity";
private static final int REQUEST_CODE_RESOLUTION = 1;
private static final int REQUEST_CODE_OPENER = 2;
private GoogleApiClient mGoogleApiClient;
private boolean fileOperation = false;
private DriveId mFileId;
public DriveFile file;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "Inside the onCreate Method");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* Called when the activity will start interacting with the user.
* At this point your activity is at the top of the activity stack,
* with user input going to it.
*/
#Override
protected void onResume() {
super.onResume();
Log.i(TAG, "Inside the onResume method");
if (mGoogleApiClient == null) {
/**
* Create the API client and bind it to an instance variable.
* We use this instance as the callback for connection and connection failures.
* Since no account name is passed, the user is prompted to choose.
*/
Log.i(TAG, "Creating the API client");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
Log.i(TAG,"About to call connect method().");
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
Log.i(TAG,"inside the onStop method");
if (mGoogleApiClient != null) {
// disconnect Google API client connection
mGoogleApiClient.disconnect();
}
super.onPause();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Inside onConnectionFailed()");
// Called whenever the API client fails to connect.
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
// show the localized error dialog.
GoogleApiAvailability.getInstance().getErrorDialog(this, result.getErrorCode(), 0).show();
return;
}
/**
* The failure has a resolution. Resolve it.
* Called typically when the app is not yet authorized, and an authorization
* dialog is displayed to the user.
*/
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
/**
* It invoked when Google API client connected
* #param connectionHint
*/
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "Inside onConnected Method()");
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_LONG).show();
}
/**
* It invoked when connection suspend
* #param cause
*/
#Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
public void onClickCreateFile(View view){
fileOperation = true;
// create new contents resource
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
public void onClickOpenFile(View view){
fileOperation = false;
Log.i(TAG, "Selected the onClickOpenFile button");
// create new contents resource
Drive.DriveApi.newDriveContents(mGoogleApiClient)
.setResultCallback(driveContentsCallback);
}
/**
* Open list of folder and file of the Google Drive
*/
public void OpenFileFromGoogleDrive(){
Log.i(TAG, "Inside OpenFIleFromGoogleDrive method.");
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
//Restricting the user to only select txt and image support files for Tesseract.
.setMimeType(new String[] { "text/plain", "image/png", "image/jpeg", "image/bmp", "jpg" })
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.w(TAG, "Unable to send intent", e);
}
}
/**
* This is Result result handler of Drive contents.
* this callback method call CreateFileOnGoogleDrive() method
* and also call OpenFileFromGoogleDrive() method,
* send intent onActivityResult() method to handle result.
*/
final ResultCallback<DriveApi.DriveContentsResult> driveContentsCallback =
new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult result) {
Log.i(TAG, "Inside onResultCallback()");
if (result.getStatus().isSuccess()) {
if (fileOperation == true) {
CreateFileOnGoogleDrive(result);
} else {
OpenFileFromGoogleDrive();
}
}
}
};
/**
* Create a file in root folder using MetadataChangeSet object.
* #param result
*/
public void CreateFileOnGoogleDrive(DriveApi.DriveContentsResult result){
Log.i(TAG, "Inside createfileongoogledrive method");
final DriveContents driveContents = result.getDriveContents();
// Perform I/O off the UI thread.
new Thread() {
#Override
public void run() {
// write content to DriveContents
OutputStream outputStream = driveContents.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
try {
writer.write("Hello Joseph, you created me(: !");
writer.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("test2")
.setMimeType("text/plain")
.setStarred(true).build();
// create a file in root folder
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, changeSet, driveContents)
.setResultCallback(fileCallback);
}
}.start();
}
/**
* Handle result of Created file
*/
final private ResultCallback<DriveFolder.DriveFileResult> fileCallback = new
ResultCallback<DriveFolder.DriveFileResult>() {
#Override
public void onResult(DriveFolder.DriveFileResult result) {
if (result.getStatus().isSuccess()) {
Toast.makeText(getApplicationContext(), "file created: "+""+
result.getDriveFile().getDriveId(), Toast.LENGTH_LONG).show();
}
return;
}
};
/**
* Handle Response of selected file
* #param requestCode
* #param resultCode
* #param data
*/
#Override
protected void onActivityResult(final int requestCode,
final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_OPENER:
if (resultCode == RESULT_OK) {
mFileId = (DriveId) data.getParcelableExtra(
OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
Log.e("file id", mFileId.getResourceId() + "");
String url = "https://drive.google.com/open?id="+ mFileId.getResourceId();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
}
Related
I am using ScanApi library for socket scanner in android. But i am getting Error Code -37 every time whenever i am trying to pair through Ezactivity of this library even after giving All permissions. Can anyone please Help me Regarding this? . Thanks.
I have all the run time permissions. Still it didn't worked/
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.Toast;
import java.util.Set;
/**
* EzPairActivity
*
* This activity displays a list of already paired Bluetooth devices. In order to pair a Bluetooth
* devices, go to the Bluetooth Settings and discover the Bluetooth devices to pair with it. Then
* going back to this activity to select the scanner you would like to connect to and click the
* "pair to scanner" button. This will start the EZ Pair process.
*
* This Activity doesn't have any particular code for the Screen rotation so it is safe to be
* recreated at each rotation. The Application object is the one maintaining states.
*
* #author EricG
*/
public class EzPairActivity extends Activity {
private final int PROGRESS_DIALOG = 1;
private ArrayAdapter<String> _adapterDevices;
private String _deviceSelectedToPairWith;
private String _hostBluetoothAddress;
private CheckedTextView _previousSelection;
private Context _context;
/**
* Progress is a Progress Dialog used to display some UI while EZ Pair is processing
*
* #author EricG
*/
private class Progress extends ProgressDialog {
public Progress(Context context) {
super(context);
}
/**
* #see android.app.ProgressDialog#onStart()
*
* Start the EZ Pair process.
*/
#Override
public void onStart() {
super.onStart();
// THIS IS THE STARTING POINT OF EZ PAIR PROCESS
Intent intent = new Intent(SingleEntryApplication.START_EZ_PAIR);
// remove the bluetooth address and keep only the device friendly name
if (_deviceSelectedToPairWith != null) {
if (_deviceSelectedToPairWith.length() > 18) {
_deviceSelectedToPairWith = _deviceSelectedToPairWith
.substring(0, _deviceSelectedToPairWith.length() - 18);
}
intent.putExtra(SingleEntryApplication.EXTRA_EZ_PAIR_DEVICE,
_deviceSelectedToPairWith);
intent.putExtra(SingleEntryApplication.EXTRA_EZ_PAIR_HOST_ADDRESS,
_hostBluetoothAddress);
sendBroadcast(intent);
}
}
/**
* #see android.app.Activity#onStop()
*
* Stop the EZ Pair process. This will restore ScanAPI Configuration to its original
* settings
*/
#Override
protected void onStop() {
super.onStop();
// THIS WILL STOP THE EZ PAIR PROCESS
Intent intent = new Intent(SingleEntryApplication.STOP_EZ_PAIR);
sendBroadcast(intent);
}
}
private Progress _progress;
/**
* handler to receive the broadcast of ERROR MESSAGE or EZ PAIR COMPLETED from the application
* object. In both cases, the progress dialog is dismissed.
*/
private final BroadcastReceiver _broadcastReveiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().contains(SingleEntryApplication.NOTIFY_ERROR_MESSAGE)) {
dismissDialog(PROGRESS_DIALOG);
String text = intent.getStringExtra(SingleEntryApplication.EXTRA_ERROR_MESSAGE);
if(text.contains("27") || text.contains("47")){
Toast.makeText(context, "Failed! Please make sure that scanner is already paired", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(context, "Failed to connect scanner" + text, Toast.LENGTH_LONG).show();
}
} else if (intent.getAction()
.contains(SingleEntryApplication.NOTIFY_EZ_PAIR_COMPLETED)) {
dismissDialog(PROGRESS_DIALOG);
Toast.makeText(context, "Pairing Completed", Toast.LENGTH_LONG).show();
finish();
}
}
};
/**
* Handler of the Pair to scanner button. If a scanner has been previously selected this will
* display the Progress Dialog that will start the EZ Pair process
*/
private final OnClickListener _onStartPairing = new OnClickListener() {
#Override
public void onClick(View v) {
if (_deviceSelectedToPairWith != null) {
showDialog(PROGRESS_DIALOG);
}
}
};
/**
* Handler of the Bluetooth Paired device list onItemClick. This selects the scanner to EZ Pair
* with.
*/
private final OnItemClickListener _onPairedDeviceSelected = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
CheckedTextView ctv = (CheckedTextView) arg1;
if (ctv != null) {
_deviceSelectedToPairWith = ctv.getText().toString();
ctv.setChecked(true);
if (_previousSelection != null) {
_previousSelection.setChecked(false);
}
_previousSelection = ctv;
}
}
};
/**
* Entry point of this EZ Pair activity
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ezpair);
_context = this;
// select the broadcast this activity should receive
// from the Application
IntentFilter filter;
filter = new IntentFilter(SingleEntryApplication.NOTIFY_ERROR_MESSAGE);
registerReceiver(_broadcastReveiver, filter);
filter = new IntentFilter(SingleEntryApplication.NOTIFY_EZ_PAIR_COMPLETED);
registerReceiver(_broadcastReveiver, filter);
// create an adapter for the ListView of the Paired Bluetooth device
// in this particular case we would like a single choice line
_adapterDevices = new ArrayAdapter<String>(getApplicationContext(),
R.layout.simple_list_item_single_choice);
// install the handler for the "Pair to scanner" button
Button btn = (Button) findViewById(R.id.buttonPairToScanner);
if (btn != null) {
btn.setOnClickListener(_onStartPairing);
}
// install the Adapter and the handler for
// the Bluetooth Paired device ListView
ListView lv = (ListView) findViewById(R.id.listViewScanners);
if (lv != null) {
lv.setAdapter(_adapterDevices);
lv.setOnItemClickListener(_onPairedDeviceSelected);
}
// retrieve the host Bluetooth address and the list of
// paired device for which the Bluetooth address starts
// by the Socket identifier
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
_hostBluetoothAddress = bluetoothAdapter.getAddress();
} else {
_hostBluetoothAddress = Settings.Secure.getString(getContentResolver(), "bluetooth_address");
if(_hostBluetoothAddress == null){
_hostBluetoothAddress = bluetoothAdapter.getAddress();
}
}
try {
_hostBluetoothAddress = _hostBluetoothAddress.replace(":", "");
}catch (Exception e){
Log.e("EzPair", e.getMessage(), e);
}
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
// if((device.getAddress().toLowerCase().contains("00:c0:1b")||
// (device.getAddress().toLowerCase().contains("00:06:66"))))
_adapterDevices.add(device.getName() + "\n" + device.getAddress());
}
} else {
String noDevices = "none_paired"; //getResources().getText("none_paired").toString();
_adapterDevices.add(noDevices);
if (btn != null) {
btn.setEnabled(false);
}
}
} else {
String noBluetooth = "no bluetooth";//getResources().getText(R.string.no_bluetooth).toString();
_adapterDevices.add(noBluetooth);
if (btn != null) {
btn.setEnabled(false);
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(_broadcastReveiver);
}
/**
* used for showing the Progress Dialog
*
* #see android.app.Activity#onCreateDialog(int)
*/
#Override
protected Dialog onCreateDialog(int id) {
Dialog dialog;
if (id == PROGRESS_DIALOG) {
_progress = new Progress(_context);
_progress.setTitle("EZ Pair");
_progress.setMessage("Please wait while configuring the scanner");
_progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
//_progress.show();
dialog = _progress;
} else {
dialog = super.onCreateDialog(id);
}
return dialog;
}
}
I have a MediaRecorder in my IntentService class.
I want to
Run an IntentService to start recording audio
Run an IntentService to stop recording audio
I use IntentService because I want the audio recording to run even when my phone screen is turned off. Service runs in the background, so this is a good approach, right?
Anyways, I initiate my MediaRecorder in my IntentService at Step #1.
At Step#2, my instantiated MediaRecorder is NULL. It seems that all variable values inside the IntentService are reset, because the service ends and calls onDestroy.
What should I do? How do I keep a reference to my MediaRecorder ?
Update: Pasting my IntentService class
package com.dan190.enregistreur.BackgroundService;
import android.app.IntentService;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import com.dan190.enregistreur.RecordedFilesActivity;
import com.dan190.enregistreur.Util.RecordingStatus;
import java.io.IOException;
import java.util.Calendar;
/**
* Created by Dan on 17/03/2017.
*/
public class RecorderService extends IntentService {
private static final String TAG = RecorderService.class.getName();
private MediaRecorder mMediaRecorder;
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* #param name Used to name the worker thread, important only for debugging.
*/
public RecorderService(String name) {
super(name);
}
public RecorderService() {
super("RecorderService");
}
/**
* Handles intent.
* Unwraps intent to find out if we need to start, pause, or stop
* #param intent
*/
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Log.d(TAG, "onHandleIntent");
Bundle bundle = intent.getExtras();
int status = bundle.getInt(RecordingStatus.RECORDING_STATUS_KEY);
switch (status) {
case RecordingStatus.STANDBY:
//do nothing
break;
case RecordingStatus.RECORDING:
//if mediaPlayer is null, initiate
//set datasource
//prepare
//record
Log.d(TAG, "start recording");
startRecording();
break;
case RecordingStatus.PAUSED:
//pause
Log.d(TAG, "pause recording");
break;
case RecordingStatus.STOPPED:
//stop
Log.d(TAG, "stop recording");
stopRecording();
Intent newIntent = new Intent(this, RecordedFilesActivity.class);
startActivity(newIntent);
break;
case RecordingStatus.OPENDIR:
//open recorded files
Log.d(TAG, "open directory");
getFileName();
Intent newIntent2 = new Intent(this, RecordedFilesActivity.class);
startActivity(newIntent2);
break;
default:
break;
}
}
/**
* File stuff
*/
private static String pathName,
fileName;
public static String getPath() {
return pathName;
}
public static String getFilePath() {
return fileName;
}
private String getFileName() {
Calendar calendar = Calendar.getInstance();
PackageManager m = getPackageManager();
pathName = getPackageName();
PackageInfo p = null;
try {
p = m.getPackageInfo(pathName, 0);
} catch(PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
pathName = p.applicationInfo.dataDir;
// fileName = Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_DCIM + "/Recordings";
fileName = pathName;
fileName += String.format("/%d_%d_%d_%d_%d_%d.3gp", calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY) + 1, calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
return fileName;
}
/**
* Recorder stuff
*/
private void startRecording() {
String fileName = getFileName();
Log.d(TAG, String.format("file name is %s", fileName));
if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder();
//NOTE that mediaRecorder cannot pause for API < 24, which is Android 7.0
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setOutputFile(getFileName());
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mMediaRecorder.prepare();
} catch(IOException e) {
Log.e(TAG, "prepare() failed");
e.printStackTrace();
}
try {
mMediaRecorder.start();
} catch(IllegalStateException e) {
Log.e(TAG, e.getStackTrace().toString());
}
}
private void stopRecording() {
try {
mMediaRecorder.stop();
mMediaRecorder.reset();
} catch(RuntimeException e) {
e.printStackTrace();
}
releaseMediaRecorder();
}
private void releaseMediaRecorder() {
if (mMediaRecorder != null) {
mMediaRecorder.release();
mMediaRecorder = null;
} else {
Log.w(TAG, "mediaRecroder is already Null");
}
}
/**
* Lifecycle stuff
*/
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
}
Fixed it by using Service instead of Intent service.
This post proved helpful. Service.onDestroy() is called directly after creation, anyway the Service does its work
Basically, IntentService is designed so that it will immediately stop all services after the code within onHandleIntent is finished. Thus, I was never able to keep my MediaRecorder alive.
With a normal Service, I am able to have more control over the lifecycle of my service. I can start and stop it when I want to. With IntentService, this is not possible.
I got this code from the Internet and I modified it to upload a specific file automatically to Google Drive when starting the activity.
It is always ask me to select my Google account when I start this activity!
I want it ask about Google account once only when started for the first time after install it, How to do that?
package com.example.googledrive;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import java.util.Arrays;
import java.io.IOException;
import android.accounts.AccountManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.FileContent;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
public class MainActivity extends Activity {
static final int REQUEST_ACCOUNT_PICKER = 1;
static final int REQUEST_AUTHORIZATION = 2;
static final int REQUEST_DOWNLOAD_FILE = 3;
static final int RESULT_STORE_FILE = 4;
private static Uri mFileUri;
private static Drive mService;
private GoogleAccountCredential mCredential;
private Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// setup for credentials for connecting to the Google Drive account
mCredential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(DriveScopes.DRIVE));
// start activity that prompts the user for their google drive account
startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
// mContext = getApplicationContext();
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data)
{
switch (requestCode) {
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
mCredential.setSelectedAccountName(accountName);
mService = getDriveService(mCredential);
}
saveFileToDrive();
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
//account already picked
} else {
startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
break;
}
}
private Drive getDriveService(GoogleAccountCredential credential)
{
return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential)
.build();
}
private void saveFileToDrive()
{
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
// Create URI from real path
String path;
path = "/sdcard/DCIM/Camera/a.png";
mFileUri = Uri.fromFile(new java.io.File(path));
ContentResolver cR = MainActivity.this.getContentResolver();
// File's binary content
java.io.File fileContent = new java.io.File(mFileUri.getPath());
FileContent mediaContent = new FileContent(cR.getType(mFileUri), fileContent);
showToast("Selected " + mFileUri.getPath() + "to upload");
// File's meta data.
File body = new File();
body.setTitle(fileContent.getName());
body.setMimeType(cR.getType(mFileUri));
com.google.api.services.drive.Drive.Files f1 = mService.files();
com.google.api.services.drive.Drive.Files.Insert i1 = f1.insert(body, mediaContent);
File file = i1.execute();
if (file != null)
{
showToast("Uploaded: " + file.getTitle());
}
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (IOException e) {
e.printStackTrace();
showToast("Transfer ERROR: " + e.toString());
}
}
});
t.start();
}
public void showToast(final String toast)
{
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();
}
});
}
}
It's been a while, so you probably managed to do this by now, but I was just looking for the same thing and it's fairly easy. In the code you use and how it's used on several sites you get an Intent after calling a static method on GoogleAccountCredential.
You can also create your own, by calling a static method on AccountPicker and define a params that it's only required to pick once.
Intent accountPicker = AccountPicker.newChooseAccountIntent(null, null, new String[]{"com.google"}, false, null, null, null, null);
startActivityForResult(accountPicker, GOOGLE_ACCOUNT_PICKED);
The fourth param is what you want and you can read more about it here:
https://developers.google.com/android/reference/com/google/android/gms/common/AccountPicker?hl=en
I wanted to reduce the image size to kb's, before uploading to server, basically what my code does it, capture a image store it locally, then upload it to the server.
just wanted to reduce image size while it stores locally on the External Storage. Found a good answer here
But the problem is, I really don't know how to add up the code in the link with my code below.
New to android, please help!
package com.project.camera;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MainActivity extends Activity {
// LogCat tag
private static final String TAG = MainActivity.class.getSimpleName();
// Camera activity request codes
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
public static final int MEDIA_TYPE_IMAGE = 1;
private Uri fileUri; // file url to store image
private Button btnCapturePicture;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);
/**
* Capture image button click event
*/
btnCapturePicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// capture picture
captureImage();
}
});
// Checking camera availability
if (!isDeviceSupportCamera()) {
Toast.makeText(getApplicationContext(),
"Sorry! Your device doesn't support camera",
Toast.LENGTH_LONG).show();
// will close the app if the device does't have camera
finish();
}
}
/**
* Checking device has camera hardware or not
* */
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/**
* Launching camera app to capture image
*/
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
/**
* Here we store the file url as it will be null after returning from camera
* app
*/
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save file url in bundle as it will be null on screen orientation
// changes
outState.putParcelable("file_uri", fileUri);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// get the file url
fileUri = savedInstanceState.getParcelable("file_uri");
}
/**
* Receiving activity result method will be called after closing the camera
* */
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if the result is capturing Image
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// successfully captured the image
// launching upload activity
launchUploadActivity(true);
} else if (resultCode == RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
}
}
private void launchUploadActivity(boolean isImage){
Intent i = new Intent(MainActivity.this, UploadActivity.class);
i.putExtra("filePath", fileUri.getPath());
i.putExtra("isImage", isImage);
startActivity(i);
}
/**
* ------------ Helper Methods ----------------------
* */
/**
* Creating file uri to store image
*/
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/**
* returning image
*/
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
Config.IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "Oops! Failed create "
+ Config.IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "Selfie_" + timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
}
Use this, (I edited onPictureTaken() function to fit your needs)
Will return false if the input path does not exist and no error occured on compression.
public boolean resizeImage(String originalFilePath, String compressedFilePath) {
InputStream in = null;
try {
in = new FileInputStream(originalFilePath);
} catch (FileNotFoundException e) {
Log.e("TAG","originalFilePath is not valid", e);
}
if (in == null) {
return false;
}
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap preview_bitmap = BitmapFactory.decodeStream(in, null, options);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
preview_bitmap.compress(Bitmap.CompressFormat.JPEG, 60, stream);
byte[] byteArray = stream.toByteArray();
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(compressedFilePath);
outStream.write(byteArray);
outStream.close();
} catch (Exception e) {
Log.e("TAG","could not save", e);
}
return true;
}
I'm trying to get user location in the background.
Everything works great on my phone (htc one m7), but from some reason it's not working on two devices I tested:
Samsung galaxy s3
Sony Xperia Z1
btw: I added everything to the manifest as it should be.
this is my code:
**BackgroundLocationService **
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationRequest;
public class BackgroundLocationService extends Service implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
IBinder mBinder = new LocalBinder();
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
// Flag that indicates if a request is underway.
private boolean mInProgress;
private Boolean servicesAvailable = false;
public class LocalBinder extends Binder {
public BackgroundLocationService getServerInstance() {
return BackgroundLocationService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
mInProgress = false;
// Create the LocationRequest object
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
// Set the update interval to 5 seconds
mLocationRequest.setInterval(0);
// Set the fastest update interval to 1 second
mLocationRequest.setFastestInterval(1);
servicesAvailable = servicesConnected();
/*
* Create a new location client, using the enclosing class to
* handle callbacks.
*/
mLocationClient = new LocationClient(this, this, this);
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
return true;
} else {
return false;
}
}
public int onStartCommand (Intent intent, int flags, int startId)
{
super.onStartCommand(intent, flags, startId);
if(!servicesAvailable || mLocationClient.isConnected() || mInProgress)
return START_STICKY;
setUpLocationClientIfNeeded();
if(!mLocationClient.isConnected() || !mLocationClient.isConnecting() && !mInProgress)
{
mInProgress = true;
mLocationClient.connect();
}
return START_STICKY;
}
/*
* Create a new location client, using the enclosing class to
* handle callbacks.
*/
private void setUpLocationClientIfNeeded()
{
if(mLocationClient == null)
mLocationClient = new LocationClient(this, this, this);
}
// Define the callback method that receives location updates
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void appendLog(String text, String filename)
{
File logFile = new File(filename);
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onDestroy(){
// Turn off the request flag
mInProgress = false;
if(servicesAvailable && mLocationClient != null) {
//mLocationClient.removeLocationUpdates(callbackIntent);
// Destroy the current location client
mLocationClient = null;
}
// Display the connection status
// Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
/*
* Called by Location Services when the request to connect the
* client finishes successfully. At this point, you can
* request the current location or start periodic updates
*/
#Override
public void onConnected(Bundle bundle) {
// Request location updates using static settings
Intent intent = new Intent(this, LocationReceiver.class);
PendingIntent locationIntent = PendingIntent.getBroadcast(getApplicationContext(), 14872, intent, PendingIntent.FLAG_CANCEL_CURRENT);
mLocationClient.requestLocationUpdates(mLocationRequest, locationIntent);
}
/*
* Called by Location Services if the connection to the
* location client drops because of an error.
*/
#Override
public void onDisconnected() {
// Turn off the request flag
mInProgress = false;
// Destroy the current location client
mLocationClient = null;
// Display the connection status
// Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}
/*
* Called by Location Services if the attempt to
* Location Services fails.
*/
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
mInProgress = false;
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
// If no resolution is available, display an error dialog
} else {
}
}
}
**LocationReceiver **
import java.util.List;
import java.util.Locale;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.util.Log;
import com.google.android.gms.location.LocationClient;
public class LocationReceiver extends BroadcastReceiver {
public static double lat;
public static double alt;
public static String address;
#Override
public void onReceive(Context context, Intent intent) {
Location location = (Location) intent.getExtras().get(LocationClient.KEY_LOCATION_CHANGED);
Log.d("New Location Reciver", "location "+location.toString());
lat = location.getLatitude();
alt = location.getAltitude();
address = getAddressByCord(lat, alt, context);
}
public static String getAddressByCord(double lat, double longi, Context context) {
try {
Geocoder geo = new Geocoder(context, Locale.getDefault());
List<Address> addresses = geo.getFromLocation(lat, longi, 1);
if (addresses.isEmpty()) {
return "Waiting for Location";
} else {
if (addresses.size() > 0) {
String s = "";
if (addresses.get(0).getFeatureName() != null)
s += addresses.get(0).getFeatureName();
if (addresses.get(0).getThoroughfare() != null)
s += "," + addresses.get(0).getThoroughfare();
if (addresses.get(0).getLocality() != null)
s += "," + addresses.get(0).getLocality();
if (addresses.get(0).getAdminArea() != null)
s += "," + addresses.get(0).getAdminArea();
if (addresses.get(0).getCountryName() != null)
s += "," + addresses.get(0).getCountryName();
return s;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
if someone has any idea, Thank you!
code to check for google play services.
private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 94378;
private boolean isGooglePlay() {
int mIsGooglePlayServicesAvailable = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(context);
switch (mIsGooglePlayServicesAvailable) {
case ConnectionResult.SUCCESS:
return true;
default:
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
mIsGooglePlayServicesAvailable, this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(getSupportFragmentManager(),
"Location Updates");
}
// case ConnectionResult.SERVICE_MISSING:
// case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
// case ConnectionResult.SERVICE_DISABLED:
// case ConnectionResult.SERVICE_INVALID:
// case ConnectionResult.DATE_INVALID:
}
return false;
}
/*
* This is a class used to resolve errors with google play services It is
* copied code that doesn't run durring normal operation.
*/
public static class ErrorDialogFragment extends DialogFragment {
// Global field to contain the error dialog
private Dialog mDialog;
// Default constructor. Sets the dialog field to null
public ErrorDialogFragment() {
super();
mDialog = null;
}
// Set the dialog to display
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
// Return a Dialog to the DialogFragment.
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
I found the answer.
It was the devices own definitions.
The device was not enabling apps to use location .
thank you anyway!