I am building a cordova application which fetches JSON data from the server. One piece of information that I receive is the URL of 360 online images. I need to display those images in a photo sphere viewer (for Android). I' ve seen this API (needs cordova google play services plugin) and this library but I haven't managed to successfully use them inside the application.
Does anyone know a way of doing that? Can I open that type of image in a native intent?
Thanks in advance
Actually I managed to make it work. I am posting the solution, in case someone else finds it useful. Also created a plugin for that which can be found here
creating a simple plugin, I call from cordova the plugin class which downloads using AsyncTask an image from a URL and onPostExecute I call the Panorama activity that shows the viewer.
Intent intent = new Intent(cordova.getActivity().getApplicationContext(), PanoramaActivity.class);
intent.putExtra("filepath", file.getAbsolutePath());
cordova.getActivity().startActivity(intent);.
PanoramaActivity.java
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.panorama.Panorama;
import com.google.android.gms.panorama.PanoramaApi.PanoramaResult;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import java.io.File;
import android.os.Environment;
public class PanoramaActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener{
File file;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mClient = new GoogleApiClient.Builder(this, this, this)
.addApi(Panorama.API)
.build();
Intent i= getIntent();
Bundle b = i.getExtras();
file = new File(b.getString("filepath"));
#Override
public void onStart() {
super.onStart();
mClient.connect();
}
#Override
public void onConnected(Bundle connectionHint) {
Uri uri = Uri.fromFile(file);//Uri.parse(path);//Uri.fromFile(file);
Panorama.PanoramaApi.loadPanoramaInfo(mClient, uri).setResultCallback(
new ResultCallback<PanoramaResult>() {
#Override
public void onResult(PanoramaResult result) {
if (result.getStatus().isSuccess()) {
Intent viewerIntent = result.getViewerIntent();
Log.i(TAG, "found viewerIntent: " + viewerIntent);
if (viewerIntent != null) {
startActivity(viewerIntent);
}
} else {
Log.e(TAG, "error: " + result);
}
}
});
}
#Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "connection suspended: " + cause);
}
#Override
public void onConnectionFailed(ConnectionResult status) {
Log.e(TAG, "connection failed: " + status);
}
#Override
public void onStop() {
super.onStop();
mClient.disconnect();
Log.e(TAG, "ON Stop ");
}
Related
I've been integrating Google Drive support into my app, so when I click a button, it prompts me to sign in with my Google Account. However, I get stuck in an infinite loop whenever I try that just presents me with the same sign-in screen over and over. I'm running Android 4.4.2 (KitKat) for what it's worth.
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveId;
import com.google.android.gms.drive.OpenFileActivityBuilder;
import com.neilcpower.surveildroid.R;
import butterknife.ButterKnife;
import timber.log.Timber;
public class FilePickerActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public static final String FILE_ID = "File ID";
private static final int REQUEST_CODE_OPENER = 48957;
private static final int REQUEST_CODE_RESOLUTION = 1;
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_picker);
ButterKnife.bind(this);
}
#Override
protected void onResume() {
super.onResume();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
#Override
public void onConnected(Bundle connectionHint) {
Timber.i("Connected To Google API Client");
try {
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
.setMimeType(new String[]{"text/plain", "text/html"})
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_OPENER, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Timber.e(e, "Unable to send intent");
}
} catch (IllegalStateException e) {
// TODO Why is the first time onConnected called the client is not connected?
mGoogleApiClient.connect();
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Timber.i("GoogleApiClient connection failed: %s", connectionResult.toString());
if (!connectionResult.hasResolution()) {
GoogleApiAvailability.getInstance().getErrorDialog(this, connectionResult.getErrorCode(), 0).show();
return;
}
try {
connectionResult.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (IntentSender.SendIntentException e) {
Timber.e(e, "Exception while starting resolution activity");
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_OPENER:
if (resultCode == RESULT_OK) {
DriveId driveId = data.getParcelableExtra(OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
Intent returnIntent = new Intent();
returnIntent.putExtra(FILE_ID, driveId.encodeToString());
setResult(Activity.RESULT_OK, returnIntent);
}
finish();
break;
case REQUEST_CODE_RESOLUTION:
if (resultCode == RESULT_OK) {
mGoogleApiClient.connect();
}
break;
}
}
}
The error is (repeatedly) the following: ConnectionResult{statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent{428a9d58: android.os.BinderProxy#428a9ce0}, message=null}
The app itself is quite large, so please let me know if any other code is required to diagnose. I've been fighting with this issue for some time now and have exhausted all Google/SO solutions for similar problems.
You are creating new Google API Client in each onResume. When you are not signed in, the client asks the user to sign in. This calls onPause in your activity which disconnects from the client so the sign-in result is never retrieved. After the user signs in, you are returned to your activity and onResume is called. That creates a new Google API Client that is not signed in so it asks the user to sign in again.
Create the client in onCreate.
Also, connect should go to onStart and disconnect to onStop.
I finally figured it out!
It turns out my partner had not authorized me using my SHA-1 key on the Google Development side, so apparently this lack of permissions manifested as a constant looping of the "Please Sign In" fragment... So of course, loading from his machine would work, but my own environment couldn't compile.
Hope this helps anyone in the future who is stuck and thinking the problem is with their mobile device/cache!
I am trying to run Android Google Drive. I am using the github sample code Android Demos.
I have added google play services to my project. This is the error Iam getting:
The import com.google.android.gms.drive.events.DriveEvent.ChangeListener cannot be resolved
After reading this page (Error com.google.android.gms.drive.DriveApi.DriveContentsResult cannot be resolved)
I changed it to
The import com.google.android.gms.drive.events.ChangeListener
But, the error still exists within those two methods:
Listener cannot be resolved to a type
-
private void toggle() {
if (mSelectedFileId == null) {
return;
}
synchronized (mSubscriptionStatusLock) {
DriveFile file = Drive.DriveApi.getFile(getGoogleApiClient(),
mSelectedFileId);
if (!isSubscribed) {
Log.d(TAG, "Starting to listen to the file changes.");
file.addChangeListener(getGoogleApiClient(), changeListener);//error
isSubscribed = true;
} else {
Log.d(TAG, "Stopping to listen to the file changes.");
file.removeChangeListener(getGoogleApiClient(), changeListener);//error
isSubscribed = false;
}
}
refresh();
}
-
final private Listener<ChangeEvent> changeListener = new Listener<ChangeEvent>() {//error
#Override
public void onEvent(ChangeEvent event) {
mLogTextView.setText(String.format("File change event: %s", event));
}
};
Can anybody enlighten me on this issue?
Github code
https://github.com/googledrive/android-demos
I'm using this code:
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi;
import com.google.android.gms.drive.DriveResource;
import com.google.android.gms.drive.events.ChangeEvent;
import com.google.android.gms.drive.events.ChangeListener;
PendingResult<DriveApi.DriveIdResult> pendingResult = Drive.DriveApi.fetchDriveId(mGoogleApiClient, id);
pendingResult.setResultCallback(new ResultCallback<DriveApi.DriveIdResult>() {
#Override
public void onResult(#NonNull DriveApi.DriveIdResult driveIdResult) {
if (!driveIdResult.getStatus().isSuccess()) {
Log.d(TAG, String.format("fetch drive id error: %s", driveIdResult.getStatus().getStatusMessage()));
return;
}
mCurrentDriveId = driveIdResult.getDriveId();
DriveResource resource = mCurrentDriveId.asDriveResource();
Log.d(TAG, "received driveid from id");
PendingResult<Status> pendingChange = resource.addChangeListener(mGoogleApiClient, new ChangeListener() {
#Override
public void onChange(ChangeEvent changeEvent) {
onResourceChange(changeEvent);
}
});
pendingChange.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.d(TAG, "change listener success");
} else {
Log.d(TAG, String.format("change listener error: %s", status.getStatusMessage()));
}
}
});
}
});
But it looks like the changes are not too much realtime.
Anyway getFile() is obsolete.
I am trying to add content observer for AOSP Browser's history provider i.e., with Uri Browser.BOOKMARKS_URI. If I attach an observer, the onChange(boolean) gets called on my ICS running my Samsung GT-S7562, my JB running Samsung GT-I8262 or HTC Desire X but I don't get any notifications for AOSP Browser provider on my friend's Android 4.3 running Samsung SM-G7102. However for Google Chrome's provider, i.e., residing at content://com.android.chrome.browser/bookmarks, I get notified for changes on all android releases. Also if I query the AOSP Browser database & scan for entries, it only returns those opened in Chrome (I mean it returns Chrome's history in Browser.BOOKMARKS_URI provider).
Below is the sample service I tested for reference which is not actually required (don't mind but I think everything is quite clear above already):
package vpz.hp;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class Watcher extends Service {
private Provider Browser;
private Provider Chrome;
#Override public IBinder onBind(Intent intent) {
return null;
}
#Override public void onDestroy() {
if (this.Browser != null)
this.Browser.Stop();
if (this.Chrome != null)
this.Chrome.Stop();
super.onDestroy();
}
public final int onStartCommand(Intent Intention, int StartId, int Flags) {
this.Browser = new Provider(super.getApplicationContext(), android.provider.Browser.BOOKMARKS_URI);
this.Browser.Start();
if (Search(getApplicationContext(), "com.android.chrome")) {
this.Chrome = new Provider(super.getApplicationContext(), Uri.parse("content://com.android.chrome.browser/bookmarks"));
this.Chrome.Start();
}
return START_STICKY;
}
private static final boolean Search(Context Sender, String Package) {
try {
return Sender.getPackageManager().getPackageInfo(Package, PackageManager.GET_ACTIVITIES) != null;
} catch (NameNotFoundException Error) {
return false;
}
}
private static class Provider extends ContentObserver {
private Context Sender;
private Uri URI;
public Provider(Context Sender, Uri URI) {
super(new Handler());
this.Sender = Sender;
this.URI = URI;
}
#Override public void onChange(boolean Self) {
String Message = this.URI.toString() + " onChange(" + Self + ")";
Toast.makeText(this.Sender, Message, Toast.LENGTH_SHORT).show();
Log.e("VPZ", Message);
}
public final void Start() {
this.Sender.getContentResolver().registerContentObserver(this.URI, true, this);
}
public final void Stop() {
this.Sender.getContentResolver().unregisterContentObserver(this);
}
}
}
I have added below permission(s) already in the manifest:
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />
Is content observer on AOSP Browser has been deprecated?
These are the minimum details i need to login to my application:
guid(Global Unique ID)
fname
lname
email
gender
for Facebook login it was clear and could do this:
JSONObject json = Util.parseJson(facebook.request("me");
to get all the data specified above.
Is, there a way i can do something similar and simple with Gmail?
I read this which says:
No, there is no such SDK(like facebook) and if you want to access the
emails of Gmail then you need to implement your own email client and
for that follow the above link shared by Spk.
But i only want few user details, I don't need anything related to his mails etc.., which come under Authorization (if I am right). I only need Authentication:
I also read this, but doesn't look like it will help any.
This is the code i have now:
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.plus.GooglePlusUtil;
import com.google.android.gms.plus.PlusClient;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener {
private static final int REQUEST_CODE_RESOLVE_ERR = 7;
private ProgressDialog mConnectionProgressDialog;
private PlusClient mPlusClient;
private ConnectionResult mConnectionResult;
private String TAG = "GmailLogin";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int errorCode = GooglePlusUtil.checkGooglePlusApp(this);
if (errorCode != GooglePlusUtil.SUCCESS) {
GooglePlusUtil.getErrorDialog(errorCode, this, 0).show();
} else {
mPlusClient = new PlusClient.Builder(this, this, this)
.setVisibleActivities( "http://schemas.google.com/AddActivity",
"http://schemas.google.com/BuyActivity").build();
mConnectionProgressDialog = new ProgressDialog(this);
mConnectionProgressDialog.setMessage("Signing in...");
Button signInButton = (Button) findViewById(R.id.sign_in_button);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mConnectionResult == null) {
mConnectionProgressDialog.show();
} else {
try {
mConnectionResult
.startResolutionForResult(
MainActivity.this,
REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
// Try connecting again.
mConnectionResult = null;
mPlusClient.connect();
}
}
}
});
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (result.hasResolution()) {
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
mPlusClient.connect();
}
}
// Save the result and resolve the connection failure upon a user click.
mConnectionResult = result;
}
#Override
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == REQUEST_CODE_RESOLVE_ERR
&& responseCode == RESULT_OK) {
mConnectionResult = null;
mPlusClient.connect();
}
}
#Override
public void onConnected() {
String accountName = mPlusClient.getAccountName();
Toast.makeText(this, accountName + " is connected.", Toast.LENGTH_LONG)
.show();
}
#Override
public void onDisconnected() {
Log.d(TAG, "disconnected");
}
#Override
protected void onStart() {
super.onStart();
mPlusClient.connect();
}
#Override
protected void onStop() {
super.onStop();
mPlusClient.disconnect();
}
}
Any help is greatly appreciated, Thank You.
You should not use Gmail for user authentication using Google accounts. You can use Google + Sign-in for Android instead. This will allow you to access the user's profile information upon getting the required permissions using OAuth. Check out the guide here:
https://developers.google.com/+/mobile/android/sign-in
Those attributes would be passed as claims in the original authentication, as well as on each subsequent authentication.
Google allows you to request that they include up to Country, Email, First Name, Language, and Last Name as claims on the authentication token.
Since they do not provide a uuid, you will have to create one off of the email address. There is no support (that I could find) for retrieving gender.
I have a camera application that can also record video. (Im developing on samsung S3)
I want to be able to open the gallery on the last recorded video.
I use this code:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(file.getAbsolutePath()), "video/3gpp");
startActivity(intent);
The problem with that code is that the video immediately starts, and when it ends
the gallery activity close.
I want to be able to open the video without playing it, exactly like in my samsung S3.
thanks in advance!
To open particular image we can use this .. and its worked .
so please check with your requirement. Hope this will helps you..
import java.io.File;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class SDCARD123Activity extends Activity implements MediaScannerConnectionClient{
public String[] allFiles;
private String SCAN_PATH ;
private static final String FILE_TYPE="image/*";
private MediaScannerConnection conn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
File folder = new File("/sdcard/Photo/");
allFiles = folder.list();
// uriAllFiles= new Uri[allFiles.length];
for(int i=0;i<allFiles.length;i++)
{
Log.d("all file path"+i, allFiles[i]+allFiles.length);
}
// Uri uri= Uri.fromFile(new File(Environment.getExternalStorageDirectory().toString()+"/yourfoldername/"+allFiles[0]));
SCAN_PATH=Environment.getExternalStorageDirectory().toString()+"/Photo/"+allFiles[0];
System.out.println(" SCAN_PATH " +SCAN_PATH);
Log.d("SCAN PATH", "Scan Path " + SCAN_PATH);
Button scanBtn = (Button)findViewById(R.id.scanBtn);
scanBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
startScan();
}});
}
private void startScan()
{
Log.d("Connected","success"+conn);
if(conn!=null)
{
conn.disconnect();
}
conn = new MediaScannerConnection(this,this);
conn.connect();
}
#Override
public void onMediaScannerConnected() {
Log.d("onMediaScannerConnected","success"+conn);
conn.scanFile(SCAN_PATH, FILE_TYPE);
}
#Override
public void onScanCompleted(String path, Uri uri) {
try {
Log.d("onScanCompleted",uri + "success"+conn);
System.out.println("URI " + uri);
if (uri != null)
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
}
} finally
{
conn.disconnect();
conn = null;
}
}
}