Create an offline map using ArcGIS (.mmpk map) - android

My goal is to create an Android app which download a map from ArcGIS portal when connected to internet, then use them offline. I would like to use service pattern, so later the app can have synchronization feature. I followed a tutorial from ArcGIS here.
I am currently stuck at downloading the map part. I expect the downloaded map is in mobile map package (.mmpk), but instead my download directory have a package.info file, and a folder of geodatabase and .mmap files as image shown here. Based on my understanding, I should have an .mmpk file to use them offline.
Following the tutorial steps, I am able to (1) create an offline map task, (2) specify the parameters, and (3) examine the offline capabilities. However in step (4) generate and download the offline map, I expect the downloaded map will be in mobile map package (.mmpk) but its not; as i mentioned above with image shown. In step (5) open and use the offline map, i am able to view offline map when using mobile map package (.mmpk) file that i transfer manually into the device. I also tried to open and use my downloaded (.mmap) file but no map showed up.
My full code by steps is shown below:
(1) create an offline map task
// Load map from a portal item
final Portal portal = new Portal("http://www.arcgis.com");
final PortalItem webmapItem = new PortalItem(portal, "acc027394bc84c2fb04d1ed317aac674");
// Create map and add it to the view
myMap = new ArcGISMap(webmapItem);
mMapView = (MapView) findViewById(R.id.mapView);
mMapView.setMap(myMap);
// Create task and set parameters
final OfflineMapTask offlineMapTask = new OfflineMapTask(myMap);
(2) specify the parameters
// Create default parameters
final ListenableFuture<GenerateOfflineMapParameters> parametersFuture = offlineMapTask.createDefaultGenerateOfflineMapParametersAsync(areaOfInterest);
parametersFuture.addDoneListener(new Runnable() {
#Override
public void run() {
try {
final GenerateOfflineMapParameters parameters = parametersFuture.get();
// Update the parameters if needed
// Limit maximum scale to 5000 but take all the scales above (use 0 as a MinScale)
parameters.setMaxScale(5000);
parameters.setIncludeBasemap(false);
// Set attachment options
parameters.setAttachmentSyncDirection(GenerateGeodatabaseParameters.AttachmentSyncDirection.UPLOAD);
parameters.setReturnLayerAttachmentOption(GenerateOfflineMapParameters.ReturnLayerAttachmentOption.EDITABLE_LAYERS);
// Request the table schema only (existing features won't be included)
parameters.setReturnSchemaOnlyForEditableLayers(true);
// Update the title to contain the region
parameters.getItemInfo().setTitle(parameters.getItemInfo().getTitle() + " (Central)");
// Create new item info
final OfflineMapItemInfo itemInfo = new OfflineMapItemInfo();
// Override thumbnail with the new image based on the extent
final ListenableFuture<Bitmap> exportImageFuture = mMapView.exportImageAsync();
exportImageFuture.addDoneListener(new Runnable() {
#Override
public void run() {
try {
Bitmap mapImage = exportImageFuture.get();
// Scale to thumbnail size
Bitmap thumbnailImage = Bitmap.createScaledBitmap(mapImage, 200, 133, false);
// Convert to byte[]
ByteArrayOutputStream stream = new ByteArrayOutputStream();
thumbnailImage.compress(Bitmap.CompressFormat.JPEG, 50, stream);
byte[] thumbnailBytes = stream.toByteArray();
stream.close();
// Set values to the itemInfo
itemInfo.setThumbnailData(thumbnailBytes);
itemInfo.setTitle("Water network (Central)");
itemInfo.setSnippet(webmapItem.getSnippet()); // Copy from the source map
itemInfo.setDescription(webmapItem.getDescription()); // Copy from the source map
itemInfo.setAccessInformation(webmapItem.getAccessInformation()); // Copy from the source map
itemInfo.getTags().add("Water network");
itemInfo.getTags().add("Data validation");
// Set metadata to parameters
parameters.setItemInfo(itemInfo);
} catch (Exception e) {
e.printStackTrace();
}
}
});
(3) examine the offline capabilities
final ListenableFuture<OfflineMapCapabilities> offlineMapCapabilitiesFuture =
offlineMapTask.getOfflineMapCapabilitiesAsync(parameters);
offlineMapCapabilitiesFuture.addDoneListener(new Runnable() {
#Override
public void run() {
try {
OfflineMapCapabilities offlineMapCapabilities = offlineMapCapabilitiesFuture.get();
if (offlineMapCapabilities.hasErrors()) {
// Handle possible errors with layers
for (java.util.Map.Entry<Layer, OfflineCapability> layerCapability :
offlineMapCapabilities.getLayerCapabilities().entrySet()) {
if (!layerCapability.getValue().isSupportsOffline()) {
showMessage(layerCapability.getKey().getName() + " cannot be taken offline.");
showMessage("Error : " + layerCapability.getValue().getError().getMessage());
}
}
// Handle possible errors with tables
for (java.util.Map.Entry<FeatureTable, OfflineCapability> tableCapability :
offlineMapCapabilities.getTableCapabilities().entrySet()) {
if (!tableCapability.getValue().isSupportsOffline()) {
showMessage(tableCapability.getKey().getTableName() + " cannot be taken offline.");
showMessage("Error : " + tableCapability.getValue().getError().getMessage());
}
}
} else {
// All layers and tables can be taken offline!
showMessage("All layers are good to go!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
(4) generate and download the offline map
String mExportPath = String.valueOf(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)) + File.separator + "New";
showMessage(mExportPath);
// Create and start a job to generate the offline map
final GenerateOfflineMapJob generateOfflineJob =
offlineMapTask.generateOfflineMap(parameters, mExportPath);
// Show that job started
final ProgressBar progressBarOffline = (ProgressBar) findViewById(R.id.progressBarOffline);
progressBarOffline.setVisibility(View.VISIBLE);
generateOfflineJob.start();
generateOfflineJob.addJobDoneListener(new Runnable() {
#Override
public void run() {
// Generate the offline map and download it
GenerateOfflineMapResult result = generateOfflineJob.getResult();
if (!result.hasErrors()) {
showMessage("no error");
mobileMapPackage = result.getMobileMapPackage();
// Job is finished and all content was generated
showMessage("Map " + mobileMapPackage.getItem().getTitle() +
" saved to " + mobileMapPackage.getPath());
// Show offline map in a MapView
mMapView.setMap(result.getOfflineMap());
// Show that job completed
progressBarOffline.setVisibility(View.INVISIBLE);
} else {
showMessage("error");
// Job is finished but some of the layers/tables had errors
if (result.getLayerErrors().size() > 0) {
for (java.util.Map.Entry<Layer, ArcGISRuntimeException> layerError : result.getLayerErrors().entrySet()) {
showMessage("Error occurred when taking " + layerError.getKey().getName() + " offline.");
showMessage("Error : " + layerError.getValue().getMessage());
}
}
if (result.getTableErrors().size() > 0) {
for (java.util.Map.Entry<FeatureTable, ArcGISRuntimeException> tableError : result.getTableErrors().entrySet()) {
showMessage("Error occurred when taking " + tableError.getKey().getTableName() + " offline.");
showMessage("Error : " + tableError.getValue().getMessage());
}
}
// Show that job completed
progressBarOffline.setVisibility(View.INVISIBLE);
}
}
});
(5) open and use the offline map
// Create the mobile map package
final MobileMapPackage mapPackage = new MobileMapPackage(mobileMapPackage.getPath());
// Load the mobile map package asynchronously
mapPackage.loadAsync();
// Add done listener which will invoke when mobile map package has loaded
mapPackage.addDoneLoadingListener(new Runnable() {
#Override
public void run() {
// Check load status and that the mobile map package has maps
if(mapPackage.getLoadStatus() == LoadStatus.LOADED && mapPackage.getMaps().size() > 0){
// Cdd the map from the mobile map package to the MapView
mMapView.setMap(mapPackage.getMaps().get(0));
}else{
// Log an issue if the mobile map package fails to load
showMessage(mapPackage.getLoadError().getMessage());
}
}
});
showMessage() in my code is showing Toast.
public void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
I worry if my .mmpk expectation is wrong, or my step goes wrong somewhere because I still not fully understand the whole process. This is my first time working with ArcGIS map in Android. I could not find much sample code to experiment, so really appreciate someone who could help.
Thank you!

The task created an exploded mobile map package, which works just the same as a .mmpk file. Open it like this:
final MobileMapPackage mapPackage =
new MobileMapPackage("/data/com.geoinfo.asmasyakirah.arcgis/files/Documents/New");
(If you can't access it there, you might want to generate the mobile map package in Environment.getExternalStorageDirectory() instead of Environment.DIRECTORY_DOCUMENTS.)
According to the documentation for the MobileMapPackage constructor:
Creates a new MobileMapPackage from the .mmpk file or exploded mobile map package at the given path.
If you really must have it as a .mmpk file, simply zip it using an Android API for making zip files and name it .mmpk instead of .zip.

Kinda late on the topic but i had several days working on this and found out something that may help some of you :
I created my mapData via this class : https://github.com/Esri/arcgis-runtime-samples-java/blob/master/src/main/java/com/esri/samples/map/generate_offline_map/GenerateOfflineMapSample.java
As you can see it creates a folder containing package.info + p13 (in which you find geodatabase file + mmap file)
WHen i tried offline to load this data, no errors appeared but the layer was empty and i could just see the carroying.
In fact after much more tries, i had to check that besides geodatabase and mmap file i could find a .tpk file (TilePackaged)
This one was never available (somehow due to network issues during the online download) and nothing alerted me.
Now that this tpk file is there, all items are clearly displayed like 'water network'
TL;DR; : check that tpk file is donwloaded during the online preparation.

Related

How to update an entry in Contentful

I am not getting to update my entry, before I try to update, I unpublish the entry using client.entries().async().unPublish(entry), and it works, but when I try to update using the code below, I receive the follow message: java.lang.IllegalArgumentException: entry must have a space associated.
What am I doing wrong?
final CMAClient client =
new CMAClient
.Builder()
.setAccessToken(contentfulConnection.getCMA_TOKEN())
.build();
final CMASystem sys = new CMASystem();
sys.setId(entryID).setVersion(CurrentVersion);
CMAEntry entry;
entry.setField("name", "en-US", "TEST").setSystem(sys);
entry.setSpaceId(SPACE_ID);
entry.setID("entryID");
client.entries().async().update(entry, new CMACallback<CMAEntry>() {
#Override protected void onSuccess(CMAEntry entry) {
// Successfully created a new entry.
new AlertDialog.Builder(ctx).setTitle("Contentful")
.setMessage("Creation of an entry was successful." +"\n\nResult:
" +
entry).show();
} }
#Override protected void onFailure(RuntimeException exception) {
// An error occurred! Inform the user.
new AlertDialog.Builder(ctx)
.setTitle("Contentful Error")
.setMessage("Could not create an entry." +
"\n\nReason: " + exception.toString())
.show();
System.out.println(exception.toString());
super.onFailure(exception);
}
}
);
I am a maintainer of the Contentful Java SDK.
The recommended way of using the update method is to first fetch an item, change its data and then update it again.
If you follow this link to our documentation, and select the create/update an entry button, you'll see a code snippets on how to update entries. Please select Android platform to see it for Android.
I hope this helps you a bit further.

MapBox GL Android: Offline Maps from custom tile source downloaded but not used

for our app, I'm currently integrating map box with a custom map tile surce (as described here). Everything runs fine with a working internet connection, using the OfflineManager and OfflineTilePyramidRegionDefinition I can download tiles and find them in the mbgl-offline.db but they appear to not be used in the app. The offline regions are reported to be complete, but just don't show up. As I understand the offline documentation, after downloading tiles, everything else is "hands off".
I've tried several different sources (e.g., OpenMapTiles.org), as we are still in the process of setting up our own map tile server.
Am I missing something here? I really appreciate any leads.
Best,
Phil
Update:
Here's some more information:
The XML-Layout
<com.mapbox.mapboxsdk.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
mapbox:center_latitude="51"
mapbox:center_longitude="7"
mapbox:style_url="http://demo.tileserver.org/styles/klokantech-basic.json"
mapbox:zoom="1"/>
The code for downloading the map data:
// Set up the OfflineManager
OfflineManager offlineManager = OfflineManager.getInstance(context);
// Create a bounding box for the offline region
LatLngBounds latLngBounds = new LatLngBounds.Builder()
.include(new LatLng(6, 50))
.include(new LatLng(8, 52))
.build();
// Define the offline region
OfflineTilePyramidRegionDefinition definition = new OfflineTilePyramidRegionDefinition(
mapView.getStyleUrl(),
latLngBounds,
0,
9, // also tried other zoom levels
context.getResources().getDisplayMetrics().density);
// Set the metadata
byte[] metadata;
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put(JSON_FIELD_REGION_NAME, "Cologne");
String json = jsonObject.toString();
metadata = json.getBytes(JSON_CHARSET);
} catch (Exception exception) {
Log.e("Failed to encode metadata: " + exception.getMessage());
metadata = null;
}
// Create the region asynchronously
offlineManager.createOfflineRegion(
definition,
metadata,
new OfflineManager.CreateOfflineRegionCallback() {
#Override
public void onCreate(OfflineRegion offlineRegion) {
offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE);
// Monitor the download progress using setObserver
offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() {
#Override
public void onStatusChanged(OfflineRegionStatus status) {
// Calculate the download percentage and update the progress bar
double percentage = status.getRequiredResourceCount() >= 0
? (100.0 * status.getCompletedResourceCount() / status.getRequiredResourceCount()) :
0.0;
if (status.isComplete()) {
// Download complete
Log.d("Region downloaded successfully.");
ReadOSRMRouteTask readOSRMRouteTask = new ReadOSRMRouteTask();
readOSRMRouteTask.execute();
} else if (status.isRequiredResourceCountPrecise()) {
// Switch to determinate state
Log.d((int) Math.round(percentage) + "% downloaded");
}
}
#Override
public void onError(OfflineRegionError error) {
// If an error occurs, print to logcat
Log.e("onError reason: " + error.getReason());
Log.e("onError message: " + error.getMessage());
}
#Override
public void mapboxTileCountLimitExceeded(long limit) {
// Notify if offline region exceeds maximum tile count
Log.e("Mapbox tile count limit exceeded: " + limit);
}
});
}
#Override
public void onError(String error) {
Log.e("Error: " + error);
}
});
While downloading the map data, the log basically just spammed a lot of HTTP 200s, so everything seems fine on this end. Additionally, the offline packages are reported complete and the sqlite-db seems fine as well.
When starting the app in offline mode, this is basically the log:
D/mbgl: [JNI]: nativeCreate
/com.mapbox.mapboxsdk.maps.MapView: MapView start Telemetry...
/MapboxEventManager: Telemetry initialize() called...
/MapboxEventManager: Mapbox Telemetry has already been initialized.
D/mbgl: [JNI]: nativeInitializeDisplay
D/mbgl: [JNI]: nativeInitializeContext
I/MapboxEventManager: flushEventsQueueImmediately() called...
D/MapboxEventManager: turnstile event pushed.
W/MapboxEventManager: Not connected to network, so empty events cache
and return without attempting to send events
I/com.mapbox.mapboxsdk.http.HTTPRequest: Request failed due to a
connection error: No Internet connection available.
D/mbgl: [JNI]: nativeViewResize
D/mbgl: [JNI]: nativeCreateSurface
D/mbgl: [JNI]: nativeFramebufferResize
I/TelemetryService: onStartCommand() called
D/mbgl: [JNI]: nativeViewResize
D/mbgl: [JNI]: nativeFramebufferResize
I/Timeline: Timeline: Activity_idle id:
android.os.BinderProxy#41bd28b8 time:609768
W/MapboxEventManager: Not connected to network, so empty events cache
and return without attempting to send events
Can you provide more information on the issue such as any log output and the behavior this is happening vs what you expected? Make sure you are using the same mapbox style URL for both the offline download and your mapviews style.

After downloading file .obb not find the next scene

I am making an application in Unity3D and I have a problem with the file .obb. After downloading the file .obb from my dropbox try to open the next scene and tells me I can not find it. If I close the application and return open functioning OK. What can be?
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using UnityEngine.UI;
public class DownloadFile : MonoBehaviour {
private string path;
private string url = "";
private float m_CurrentValue = 0;
public GameObject btnStart;
private string nextScene = "Splash";
void log( string t )
{
print("MYLOG " + t);
}
// Use this for initialization
void Start ()
{
CheckObb ();
}
// Update is called once per frame
void Update () {
}
void CheckObb()
{
if (!GooglePlayDownloader.RunningOnAndroid())
{
log ( "Use GooglePlayDownloader only on Android device!");
return;
}
string expPath = GooglePlayDownloader.GetExpansionFilePath();
if (expPath == null)
{
log("External storage is not available!");
}
else
{
string package = GooglePlayDownloader.Package();
int version = GooglePlayDownloader.Version();
path = String.Format("{0}/main.{1}.{2}.obb", expPath, version, package);
url = String.Format("https://www.dropbox.com/s/xxxxxxxxxxxxxx/main.{0}.{1}.obb?dl=1", version, package);
if (File.Exists(path))
{
// After downloading the file if you close the game and you become open, OK ¿?
Application.LoadLevel(nextScene);
}
else
{
//check if directory doesn't exit
if(!Directory.Exists(expPath))
{
//if it doesn't, create it
Directory.CreateDirectory(expPath);
}
btnStart.SetActive(true);
}
}
}
// Click Start button download obb
public void ClickStart()
{
btnStart.SetActive(false);
StartCoroutine(DownloadObb());
}
// Download obb
IEnumerator DownloadObb() {
WWW download = new WWW(url);
while( !download.isDone ) {
m_CurrentValue = download.progress * 100;
yield return null;
}
if (!string.IsNullOrEmpty(download.error)) {
//Error
} else
{
// success!
File.WriteAllBytes (path, download.bytes);
// Here says that there is the scene
Application.LoadLevel(nextScene);
}
}
}
I tried to upload the apk and obb as alpha version in the developer console but when I go to download the .obb tells me this:
"Download failed because the resources could not be found"
Thanks.
I follow this tutorial in order to split my Unity app into *.obb file. It help me a lot.
Now, when I was performing my test in GooglePlay as an Alpha version everything goes OK, the download of the obb file and the process in the app but it doesn`t load my first scene.
It took me a lot to notice that when I put the loader as the scene 0 my index to load the next Scene was wrong. I know it is a poor error but thats the History behind my 10 hours research.
Hope you'll find useful.

Android service file observer strange behavior

I need to implement a service in android that must be able to monitor a folder to detect a certain file and read what it contains. I'm having a strange behavior with my code and I can't find the reason. This is my relevant code.
public void onCreate(){
lectorFichCSV = new LectorFichCSV(); //object to read CSV files
ftpFileObserver = new FileObserver(filePath.getAbsolutePath()){
public void onEvent(int event, String file) {
if((FileObserver.CREATE & event) != 0){
Log.i("INFO: ", filePath.getAbsolutePath() + "/" + file + " is created");
if(file.substring(0,3).equals("RVE")){ //If file is created and the one I expect
try{
Log.i("INFO: ", "We have a RVE answer");
is = new FileInputStream(filePath + "/" + file);
lineaVent = lectorFichCSV.parseCSVFileAsList(is); //Get information in a list
//Get dao from ORMLite
dao = getHelper().getLineaVentDao();
Iterator<String[]> iterator = lineaVent.iterator();
if(iterator.hasNext()){
String[] aux = iterator.next();
Log.i("INFO:", "CodLineaVent "+aux[0]);
if(aux[2].equals("S")){
//Update DB information accordin to my file
UpdateBuilder<LineaVent, Integer> updateBuilder = dao.updateBuilder();
updateBuilder.where().eq("_id", aux[0]);
updateBuilder.updateColumnValue("valido", true);
updateBuilder.updateColumnValue("saldo", true);
updateBuilder.update();
lineaVent.clear();
}else if(aux[2].equals("N")){
UpdateBuilder<LineaVent, Integer> updateBuilder = dao.updateBuilder();
updateBuilder.where().eq("_id", aux[0]);
updateBuilder.updateColumnValue("saldo", false);
updateBuilder.update();
lineaVent.clear();
}
File fileToDel = new File(filePath + "/" + file);
fileToDel.delete();
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(SQLException e){
e.printStackTrace();
}
}
I debugged the code and sometimes is working and sometimes I get lineaVent.size() == 0. I'm going crazy with this, I'm thinking, is it possible that events occurs faster than the creation of my file? that would be the reason when I tried to parse my CSV file into my List object is size = 0? In that case I'm not getting any FileNotFoundException.
Any help will be appreciate. Thank you.
I am not an expert with the inotify POSIX API that, IIRC, underlies FileObserver. However, given that there are separate events for CREATE, MODIFY, and CLOSE_WRITE, it stands to reason that the CREATE event is solely for file creation -- in other words, allocating a new entry in the filesystem for the file. That would either create an empty file, or perhaps a file with some initial load of bytes, but where other MODIFY calls might be needed to write out the full contents. CLOSE_WRITE would then be called to indicate that whoever was writing to the file has now closed their file handle.
Hence, if you are watching for some file to be created, to read it in, watch for CREATE, then watch for CLOSE_WRITE on that same file, and then try to read it, and see if that works better.

Using Google Cloud Storage JSON api in android

I want to upload image on Google Cloud Storage from my android app. For that I searched and found that GCS JSON Api provides this feature. I did a lot of research for Android sample which demonstrates its use. On the developer site they have provided code example that only support java. I don't know how to use that API in Android. I referred this and this links but couldn't get much idea. Please guide me on how i can use this api with android app.
Ok guys so I solved it and got my images being uploaded in Cloud Storage all good.
This is how:
Note: I used the XML API it is pretty much the same.
First, you will need to download a lot of libraries.
The easiest way to do this is create a maven project and let it download all the dependencies required. From this sample project :
Sample Project
The libraries should be:
Second, you must be familiar with Cloud Storage using the api console
You must create a project, create a bucket, give the bucket permissions, etc.
You can find more details about that here
Third, once you have all those things ready it is time to start coding.
Lets say we want to upload an image:
Cloud storage works with OAuth, that means you must be an authenticated user to use the API. For that the best way is to authorize using Service Accounts. Dont worry about it, the only thing you need to do is in the API console get a service account like this:
We will use this service account on our code.
Fourth, lets write some code, lets say upload an image to cloud storage.
For this code to work you must put your key generated in step 3 in assets folder, i named it "key.p12".
I don't recommend you to do this on your production version, since you will be giving out your key.
try{
httpTransport= new com.google.api.client.http.javanet.NetHttpTransport();
//agarro la key y la convierto en un file
AssetManager am = context.getAssets();
InputStream inputStream = am.open("key.p12"); //you should not put the key in assets in prod version.
//convert key into class File. from inputstream to file. in an aux class.
File file = UserProfileImageUploadHelper.createFileFromInputStream(inputStream,context);
//Google Credentianls
GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(Collections.singleton(STORAGE_SCOPE))
.setServiceAccountPrivateKeyFromP12File(file)
.build();
String URI = "https://storage.googleapis.com/" + BUCKET_NAME+"/"+imagename+".jpg";
HttpRequestFactory requestFactory = httpTransport.createRequestFactory(credential);
GenericUrl url = new GenericUrl(URI);
//byte array holds the data, in this case the image i want to upload in bytes.
HttpContent contentsend = new ByteArrayContent("image/jpeg", byteArray );
HttpRequest putRequest = requestFactory.buildPutRequest(url, contentsend);
com.google.api.client.http.HttpResponse response = putRequest.execute();
String content = response.parseAsString();
Log.d("debug", "response is:"+response.getStatusCode());
Log.d("debug", "response content is:"+content);} catch (Exception e) Log.d("debug", "Error in user profile image uploading", e);}
This will upload the image to your cloud bucket.
For more info on the api check this link Cloud XML API
Firstly, You should get the below information by registering your application in the GCP console.
private final String pkcsFile = "xxx.json";//private key file
private final String bucketName = "your_gcp_bucket_name";
private final String projectId = "your_gcp_project_id";
Once you get the credentials, you should put the private key (.p12 or .json) in your assets folder. I'm using JSON format private key file. Also, you should update the image location to upload.
#RequiresApi(api = Build.VERSION_CODES.O)
public void uploadImageFile(String srcFileName, String newName) {
Storage storage = getStorage();
File file = new File(srcFileName);//Your image loaction
byte[] fileContent;
try {
fileContent = Files.readAllBytes(file.toPath());
} catch (IOException e) {
e.printStackTrace();
return;
}
if (fileContent == null || fileContent.length == 0)
return;
BlobInfo.Builder newBuilder = Blob.newBuilder(BucketInfo.of(bucketName), newName);
BlobInfo blobInfo = newBuilder.setContentType("image/png").build();
Blob blob = storage.create(blobInfo, fileContent);
String bucket = blob.getBucket();
String contentType = blob.getContentType();
Log.e("TAG", "Upload File: " + contentType);
Log.e("File ", srcFileName + " uploaded to bucket " + bucket + " as " + newName);
}
private Storage getStorage() {
InputStream credentialsStream;
Credentials credentials;
try {
credentialsStream = mContext.getAssets().open(pkcsFile);
credentials = GoogleCredentials.fromStream(credentialsStream);
} catch (IOException e) {
e.printStackTrace();
return null;
}
return StorageOptions.newBuilder()
.setProjectId(projectId).setCredentials(credentials)
.build().getService();
}

Categories

Resources