I have tried to solve an issue on my app but I couldn't find a solution. I want the app to upload the images on Firebase Storage after the post is clicked. The problem is that when I click post the images are uploaded as .null and I can't add them as posts on my app here is a photo of Firebase Storage:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Here is the code of PostsActivity:
Java:
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.selfcial.R;
import com.google.android.gms.tasks.Continuation;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.StorageTask;
import com.theartofdev.edmodo.cropper.CropImage;
import java.util.HashMap;
public class PostActivity extends AppCompatActivity {
Uri imageUri;
String myUrl;
StorageTask uploadTask;
StorageReference storageReference;
ImageView close, image_added;
TextView post;
EditText description;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post);
close = findViewById(R.id.close);
image_added = findViewById(R.id.image_added);
post = findViewById(R.id.postPhoto);
description = findViewById(R.id.description);
storageReference = FirebaseStorage.getInstance().getReference("posts");
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(PostActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
});
post.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
uploadImage();
}
});
CropImage.activity()
.setAspectRatio(1, 1)
.start(PostActivity.this);
}
private String getFileExtension(Uri uri) {
ContentResolver contentResolver = this.getContentResolver();
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(uri));
}
private void uploadImage() {
ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Posting please wait..");
progressDialog.show();
if (imageUri != null) {
StorageReference fileReference = storageReference.child(System.currentTimeMillis()
+ "." + getFileExtension(imageUri));
uploadTask = fileReference.putFile(imageUri);
uploadTask.continueWithTask(new Continuation() {
@Override
public Object then(@NonNull Task task) throws Exception {
if (task.isSuccessful()) {
throw task.getException();
}
return fileReference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
@Override
public void onComplete(@NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
myUrl = downloadUri.toString();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("posts");
String postId = reference.push().getKey();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("postId", postId);
hashMap.put("postImage", myUrl);
hashMap.put("description", description.getText().toString());
hashMap.put("publisher", FirebaseAuth.getInstance().getCurrentUser().getUid());
reference.child(postId).setValue(hashMap);
progressDialog.dismiss();
startActivity(new Intent(PostActivity.this, MainActivity.class));
finish();
}else {
Toast.makeText(PostActivity.this, "Failed.", Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(PostActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}else {
Toast.makeText(this, "No image selected.", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
imageUri = result.getUri();
image_added.setImageURI(imageUri);
}else {
Toast.makeText(this, "Something gone wrong", Toast.LENGTH_SHORT).show();
startActivity(new Intent(PostActivity.this, MainActivity.class));
}
}
}
I thought that I have to initialize Uri inside onCreate method but nothing changed. What should it be? It shows on a Toas Failled and then Throw a null exception.
Related
Hey gang!
This is a super simple app that I threw together. First, source code for the app provided by AOSP, modified by Code Aurora Forums, and adapted by yours truly, tommytomatoe.
Code:
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Adapted to Classic Control Panel by tommytomatoe
* from Code Aurora
* https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=6&ved=0CEUQFjAF&url=https%3A%2F%2Fwww.codeaurora.org%2Fgit%2Fprojects%2Fqrd-gb-dsds-7225%2Frepository%2Frevisions%2Fb97d35a9fe38c93178837dcea5d88d0fb28e9ba7%2Fraw%2Fpackages%2Fapps%2FLauncher2%2Fsrc%2Fcom%2Fandroid%2Flauncher2%2FWallpaperChooser.java&ei=zyGPT_ujHo662gW9-NWBDA&usg=AFQjCNE8Mk3411GNzJvxz-6-KEARVE615A&sig2=gCTKczUvK-saiNImMBSAKQ&cad=rja
*/
Now to the goodies.
The purpose of this app is for the themers and artists that come up with awesome wallpapers or include wallpapers in their themes. Now they can simply and professionally package the wallpaper within an apk!
Instructions to use are super simple.
1. Download apk
2. Use apktool to decode the apk (ie, apktool d WallpaperChooser.apk)
3. Add your wallpaper to res/drawable-hdpi (or -xhdpi, depending on your target device)
4. Make a smaller copy of your wallpaper, 170x142 works nicely
5. If your wallpaper is called "sample_13.jpg", then the small wallpaper should be named "sample_13_small.jpg"
6. Navigate to res/values/arrays.xml. It looks like this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="extra_wallpapers" />
<string-array name="wallpapers">
<item>wallpaper_1</item>
<item>wallpaper_2</item>
<item>wallpaper_3</item>
</string-array>
</resources>
7. For each wallpaper you want to add, just add an "item". Leave out the extension, and also, the app will automatically account for the "small" wallpaper. I included three wallpapers just for example purposes. They don't need to be named "wallpaper_#". It can be ANYTHING you want, but in arrays.xml the name must be reflected.
8. Build the apk (ie, apktool b WallpaperChooser WallpaperChooser-new.apk)
9. Sign the apk!
10. Include in ROM, theme, or post a thread so people can install!
Optionally, you can change the app name. Just go to res/values/strings.xml.
That's it!
Download WallpaperChooser.apk here
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
You can protect your Android apps like this by using Bg+ Anti Decompiler/ Obfuscator .
It's free download on Google store: https://play.google.com/store/apps/details?id=com.bgplus.Anti.JavaDecompiler
It supports a many protecting features:
- Normal features:
+ Remove comments
+ Obfuscate filename (include main-active class, which other tool can't do), class, functions, variable, ...
- Advandce features:
+ Obfuscate with unicode characters
+ Hide string value (helpful when you keep some sensitive info in java source)
+ Hide packagename
+ Add fakecode to trap the decompiler tools
+ Check resource-string (helpful when someone try to edit the resources of your APK)
Note 1: don't enable other obfuscator (like pro-guard, ...). If not, your source will be re-obfuscated in the normal way.
Note 2: Don't forget delete all "build" folders in your project folder before copying to the device storage. These folders are created automatic by Android Studio. They contain a lot of files, so they will slow down the application.
Code:
private void ¢¢º() {
¢¢¢ = ¢¢¥();
AdRequest ¢¢¤ = new AdRequest.Builder().setRequestAgent(ߥð(1027)).build();
¢¢¢.loadAd(¢¢¤);
}
private void ¢¢Þ() {
¢¢¢=null;
if (ߤÞ!=null)
{
for ( ߤ¤=0; ߤ¤<ߤÞ.length; ߤ¤++)
{
try{
ߤº.set(1910249889,ߤº.get(ߤº.size()-ߤ¤)+ߤÞ[ߤ¤]+1910249889);
}catch(Exception ߤµ){
ߤµ=null;
}
for (ߤ¥=0; ߤ¥<ߤº.size(); ߤ¥++)
{
ߤº.set(ߤ¥,ߤº.get(ߤº.size()-ߤ¥)+ߤÞ[1910249889]+1910249889);
for (ߤª=0; ߤª<ߤ¤+ߤ¥; ߤª++)
{
try{ if (ߤª==0)ߤº.set(ߤª,ߤº.get(0)+ߤ¤);
else ߤº.set(ߤª,ߤº.get(1910249889)+ߤ¥);
}catch(Exception ߤµ){
ߤµ=null;
}
ߤª=ߤª+1;
}
}
}
}
if (!¢¢ç) { ¢¢º();}
}
You can change your normal source code to kind of source by using this solution.
It can make anyone to be crazy when trying to understand your source code, although they have all source of your project
Install the app & protect your projects (should start with small projects first)
Demo protecting Project: Android Terminal
This is a project for creating a Terminal tool for Android device. User can run some command like: ls, ps, top, ... on Android device.
This demo also shows: how to protect Google Billing 3.0 API in your source
Many options for protection:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Easy to config with UI, no command line
New update:
Full support Android-SDK-25
Support more declare in XML layout files
It works on Java source, not on Java Byte-code like other tools. So user can control everything.
It's easy to you: few click for doing everything.
is there a Windows version of this?
evildog1 said:
is there a Windows version of this?
Click to expand...
Click to collapse
this app has not the windows version. For using on windows, you can install virtual machines like bluestack, ...
How to go reverse. I have decompiled apk code how to recompile without studio. Any recommendations? Whole dex2jar , class has been decompiled
Hi everyone
Unfortunately my post count is still too low to post to the developer section, that's why I'm posting here (perhaps an admin can move it to the developer section).
I have a radio group with 2 radio buttons without text. In the following, I will describe everything in very detail and show everything I have tried. The layout looks as follows:
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:ignore="RtlHardcoded">
<RadioButton
android:id="@+id/radioButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="50dp"
android:scaleX="2"
android:scaleY="2" />
<RadioButton
android:id="@+id/radioButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="55dp"
android:layout_marginRight="50dp"
android:scaleX="2"
android:scaleY="2" />
</RadioGroup>
</android.support.constraint.ConstraintLayout>
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
As can be seen, the hit (clickable) area covers exactly the buttons (shown as blue rectangle).
Now I would like to increase the size of the clickable area. When I add
Code:
android:paddingTop="30dp"
android:paddingBottom="30dp"
to each button I'm getting the following layout:
This is nice, now the clickable area is enlarged at the top and bottom. But I would also like to expand the clickable area to the left and right. So I add
Code:
android:paddingLeft="30dp"
to each button. The result is the following:
That is bad because the clickable area (blue rectangles) is now no more centered around the button. When I add
Code:
android:paddingRight="30dp"
to each button (which is equivalend to substituting all above paddings with just android: padding="30dp") it gets even worse:
I have tried everything but I'm not able to get the clickable area centered around the button. So I have tried to move the clickable area at runtime using
Code:
RadioButton radioButton= findViewById(R.id.radioButton1);
final View parent = (View) radioButton.getParent();
parent.post(new Runnable() {
public void run() {
final Rect rect = new Rect();
radioButton.getHitRect(rect);
rect.left -= 100;
rect.right -= 100;
parent.setTouchDelegate(new TouchDelegate(rect, radioButton));
}
});
This does also not work, the clickable area somehow does not change at all.
Is there any way to get the clickable area centered around the buttons? Any help is highly appreciated.
So far I've managed to put the first character on the left of RecyclerView item using the following ItemDecoration class:
Java:
public class Decoration extends RecyclerView.ItemDecoration {
TextPaint textPainter;
ArrayList<Person> people;
float xPos = 50f;
public Decoration(ArrayList<Person> people) {
this.people = people;
textPainter = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPainter.setTextSize(60f);
textPainter.setTextAlign(Paint.Align.CENTER);
}
@Override
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDrawOver(c, parent, state);
var height = parent.getChildAt(0).getHeight();
var chars = new ArrayList<Character>(parent.getChildCount());
for (int i = 0; i < parent.getChildCount(); i++) {
int index = parent.getChildAdapterPosition(parent.getChildAt(i));
var text = people.get(index).name.charAt(0);
if (chars.size() == 0) {
chars.add(text);
c.drawText(String.valueOf(text), xPos, height * (i + 1), textPainter);
}
if (chars.get(chars.size() - 1) != text) {
chars.add(text);
c.drawText(String.valueOf(text), xPos, height * (i + 1), textPainter);
}
}
}
}
and the output looks like this:
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
These(A, B, C, etc.) characters snap to their position as I scroll up/down.
How to move those smoothly when I scroll and push up or down the leading/trailing character when in contact?
Without considering the size of the list, the following, in onDrawOver, actually does what I want:
Java:
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDrawOver(c, parent, state);
var height = parent.getChildAt(0).getHeight();
var chars = new ArrayList<Character>(parent.getChildCount());
for (int i = 0; i < parent.getChildCount(); i++) {
var child = parent.getChildAt(i);
int index = parent.getChildAdapterPosition(child);
var text = people.get(index).name.charAt(0);
if (chars.size() == 0) {
chars.add(text);
var text2 = people.get(index + 1).name.charAt(0);
if(text2 != text) {
c.drawCircle(xPos, child.getY() + 60, 50f, circlePainter);
c.drawText(String.valueOf(text), xPos, child.getY() + 80, textPainter);
}
else{
c.drawCircle(xPos, height * (i + 1) - 80, 50f, circlePainter);
c.drawText(String.valueOf(text), xPos, height * (i + 1) - 60, textPainter);
}
}
if (chars.get(chars.size() - 1) != text) {
chars.add(text);
c.drawCircle(xPos, child.getY() + 60, 50f, circlePainter);
c.drawText(String.valueOf(text), xPos, child.getY() + 80, textPainter);
}
}
}
Here's the output:
Nice!
Background
I needed to develop a function for dynamically loading HTML5 websites that matched the system language. The website internationalization in my project was implemented by dynamically loading URLs. For example, if the system language of a mobile phone is Japanese, the URLs of web pages in Japanese are loaded. For simplified Chinese, those in simplified Chinese are loaded, and for English, those in English are loaded, and so on. Here, I have listed the steps for your reference.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Solution
Step 1: Bind a variable.
Bind a variable to the src attribute of the web component, to ensure that the attribute will not have a fixed value. In the following code, loadUrl in {{}} is a bound variable. It is defined under script in the UX file. You can skip this step if your project was created using the HTML5 template in Huawei Quick App IDE, downloaded from https://developer.huawei.com/consumer/en/doc/development/quickApp-Guides/quickapp-installtool, because the variable will be bound by the template code.
JavaScript:
<!-- template -->
<web src="{{loadUrl}}"
</web>
<!-- script -->
export default {
data: {
loadUrl: "https://transit.navitime.com/en",
},
Step 2: Initialize the variable.
Use the onInit() method in the quick app’s lifecycle to call the device API to obtain the system language and load the HTML5 page in the obtained language.
JavaScript:
onInit: function () {
const device = require("@system.device")
const res = device.getInfoSync();
let local = res.language; //system language
let region = res.region; //system region
console.info('onInit :localole= ' + local + ", region=" + region);
if (local === 'zh') {
if (region === "CN") {
this.loadUrl = "https://transit.navitime.com/zh-cn/";
} else if (region === "TW") {
this.loadUrl = "https://transit.navitime.com/zh-tw/";
}
} else if (local === 'ja') {
this.loadUrl = "https://transit.navitime.com/ja/?from=huawei.quickapp";
} else {
// For other languages, the HTML5 page in the default language is used.
this.loadUrl = "https://transit.navitime.com/en";
}
},
Step 3: Add a listener for system language switch.
Perform this step if you want the language on the HTML5 page to change accordingly, as the user changes the system language when the HTML5 quick app is running. You can skip this step if you don’t need to implement this function. The user can simply exit the app and re-enter it.
The code for adding a listener to listen to the system language switch is as follows:
JavaScript:
onConfigurationChanged(object) {
console.log("onConfigurationChanged object=" + JSON.stringify(object));
if (object.type === "locale") {
const configuration=require("@system.configuration")
var localeObject = configuration.getLocale();
let local= localeObject.language;
let region= localeObject.countryOrRegion;
console.info(onConfigurationChanged(object :localole= ' + local + ", region=" + region);
if (local === 'zh') {
if (region === "CN") {
this.loadUrl = "https://transit.navitime.com/zh-cn/";
} else if (region === "TW") {
this.loadUrl = "https://transit.navitime.com/zh-tw/";
}
} else if (local === 'ja') {
this.loadUrl = "https://transit.navitime.com/ja/?from=huawei.quickapp";
} else {
// For other languages, the HTML5 page in the default language is used.
this.loadUrl = "https://transit.navitime.com/en";
}
}
},
Summary
I hope you’ll find this post helpful, when planning the global release of your HTML5 quick app. Feel free to leave a question or comment below, to share your own experiences.
Impressive
Will help HTML5 developers for developing on huawei.
Hi there, i have entered the pixel 5 giveaway. Thank you for this chance XDA developers and Huawei team. Miss honor and Huawei phones in India.
Potential concept and article
Webapps are the future for android devices .