Я создаю приложение для Android, которое должно быть в состоянии сделать фотографию, а затем сохранить ее в базе данных. Я получил эту часть вниз. Однако, когда я снова пытаюсь загрузить его в свое приложение, это становится сложным.
У меня есть изображение, хранящееся как longblob в моей БД, и из показаний json в моей logcat видно, что longblob возвращается в виде строки. Очень длинная строка, с которой я не могу справиться. Когда я пытаюсь добавить в свой созданный gson класс-обертку, он просто дает мне нулевой указатель.
Теперь я видел несколько мест, которые предполагают, что я base64_encode это в моем файле php. Я нашел способ сделать это, но только добавив еще один массив в php-файл, и я бы хотел избежать обработки различных массивов в моем коде Java.
Мой php пока выглядит так:
<?php
function resultToArray($result) {
$rows = array();
while($row = $result->fetch_assoc()) {
$rows[] = $row;
foreach($rows as $key=>$value){ /* Creating this extra array is what I'm looking to avoid. */
$newArrData[$key] = $spots[$key];
$newArrData[$key]['Image'] = base64_encode($spots[$key]['Image']);
}
}
return $rows;
}
$mysqli = new mysqli("host", "username", "password", "db_to_use");
$email = $mysqli->real_escape_string($_GET['email']);
$mysqli->set_charset('utf8');
$query = ("SELECT * FROM Cards WHERE Email_FK='{$email}'");
$result = $mysqli->query($query);
$rows = resultToArray($result);
echo json_encode($rows);
$result->free();
?>
Я возвращаю 9 разных значений, включая изображение. Есть ли способ избежать создания массива newArrData, поэтому мне нужно обрабатывать только один в моем коде?
Мой класс-обертка в коде Java:
import java.io.Serializable;
/**
* Created by KasperG on 22/04/2015.
*/
public class Card implements Serializable {
private String Email_FK;
private String BarcodeNumbers;
private String MemberNumber;
private String StoreID;
private String CardID;
private String HasBarcode;
private String StoreName;
private String CustomCard;
//private Base64 Image;public Card() {
}
public Card(String barcodeNumbers, String memberNumber, String storeID, String hasBarcode, String cardID, String storeName, String CustomCard) {
this.StoreID = storeID;
if (barcodeNumbers.isEmpty()) {
this.BarcodeNumbers = null;
} else {
this.BarcodeNumbers = barcodeNumbers;
}
if (memberNumber.isEmpty()) {
this.MemberNumber = null;
} else {
this.MemberNumber = memberNumber;
}
this.HasBarcode = hasBarcode;
this.CardID = cardID;
this.StoreName = storeName;
this.CustomCard = CustomCard;
}
/*
public Card(String memberNumber, String storeID) {
this.memberNumber = memberNumber;
this.storeID = storeID;
}
*/
public String getBarcodeNumbers() {
return BarcodeNumbers;
}
public String getMemberNumber() {
return MemberNumber;
}
public String getHasBarcode() {
return HasBarcode;
}
public String getCardID() {
return CardID;
}
public String getStoreName() {
return StoreName;
}
public int getStoreID() {
return Integer.parseInt(StoreID);
}
public String getCustomStore() { return CustomCard; }
//public Base64 getImageString() { return Image; }@Override
public String toString() {
return "MemberNumber: " + MemberNumber + "\n" +
"BarcodeNumbers: " + BarcodeNumbers + "\n" +
"Store ID: " + StoreID + "\n" +
"Has Barcode " + HasBarcode + "\n" +
"Card ID: " + CardID + "\n" +
"Store Name: " + StoreName + "\n" +
"Custom Card? " + CustomCard + "\n" +
"Image String: " /*+ Image*/;
}
}
Переменная «Image» специально закомментирована, потому что, если я этого не сделаю, она вообще не будет работать!
И где я использую gson для создания классов из оболочки;
public ArrayList<Card> getCards(MyCardsScreenActivity activity) {
myCards = activity;
String email = SaveSharedPreferences.getUserName(activity);
ArrayList<Card> cards = new ArrayList<>();
try {
String link = "http://test.wallyy.com/new_get_card_info.php?email=" + email;
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(link));
HttpResponse response = client.execute(request);
String data = EntityUtils.toString(response.getEntity());
Log.d("Pass3?", data.toString());
Gson gson = new Gson();
Card[] cards1 = gson.fromJson(data.toString(), Card[].class);
for(Card card : cards1) {
cards.add(card);
Log.d("Card toString;\n", card.toString());
}
}
catch(Exception ex) {}
if (!cards.isEmpty()) {
myCards.setHasCards(true);
}
else {
myCards.setHasCards(false);
}
return cards;
}
Кто-нибудь может указать мне правильное направление здесь?
Редактировать:
Согласно предложению @CJ Wurtz, я изменил свой php-файл на этот;
while($row = $result->fetch_assoc()) {
$row['Image'] = base64_encode($row['Image']);
$rows[] = $row;
}
Тем не менее, это все еще не работает на стороне Android. Обновил мой класс-оболочку до этого;
public class Card implements Serializable {
private String Email_FK;
private String BarcodeNumbers;
private String MemberNumber;
private String StoreID;
private String CardID;
private String HasBarcode;
private String StoreName;
private String CustomCard;
private Base64 Image;public Card() {
}
Но в ту минуту, когда я добавляю переменную Image, gson не создает экземпляров класса-оболочки.
Reedit: Просто понял, что я вставил неправильный метод http. Обновленный, public ArrayList<Card> getCards(MyCardsScreenActivity) {...}
один — это тот, который я вызываю, чтобы создать экземпляры класса-обертки и добавить их в массив.
Почему бы просто не перезаписать элемент «Image» версией base64_encoded?
То есть:
while($row = $result->fetch_assoc()) {
$row['Image'] = base64_encode($row['Image']);
$rows[] = $row;
}
Я не уверен, где это $spots
массив приходит, поэтому, возможно, это решение не будет работать для вас, но, в основном, просто говоря для каждой строки, которую вы возвращаете из базы данных, обновите этот массив для строки, прежде чем добавить его в конечный массив результатов, который вы вернете.
Мой класс-обертка был настроен неправильно. Я был неуверен в том, как обработать ответ от сервера, но, сделав несколько изменений в моем классе-обертке, я заставил его работать.
Мой класс-обёртка теперь выглядит так;
import java.io.Serializable;
/**
* Created by KasperG on 22/04/2015.
*/
public class Card implements Serializable {
private String Email_FK;
private String BarcodeNumbers;
private String MemberNumber;
private String StoreID;
private String CardID;
private String HasBarcode;
private String StoreName;
private String CustomCard;
private String Image;public Card() {
}
public Card(String barcodeNumbers, String memberNumber, String storeID, String hasBarcode, String cardID, String storeName, String CustomCard, String Image) {
this.StoreID = storeID;
if (barcodeNumbers.isEmpty()) {
this.BarcodeNumbers = null;
} else {
this.BarcodeNumbers = barcodeNumbers;
}
if (memberNumber.isEmpty()) {
this.MemberNumber = null;
} else {
this.MemberNumber = memberNumber;
}
this.HasBarcode = hasBarcode;
this.CardID = cardID;
this.StoreName = storeName;
this.CustomCard = CustomCard;
this.Image = Image;
}
public String getBarcodeNumbers() {
return BarcodeNumbers;
}
public String getMemberNumber() {
return MemberNumber;
}
public String getHasBarcode() {
return HasBarcode;
}
public String getCardID() {
return CardID;
}
public String getStoreName() {
return StoreName;
}
public int getStoreID() {
return Integer.parseInt(StoreID);
}
public String getCustomStore() { return CustomCard; }
public String getImageString() { return Image; }@Override
public String toString() {
return "MemberNumber: " + MemberNumber + "\n" +
"BarcodeNumbers: " + BarcodeNumbers + "\n" +
"Store ID: " + StoreID + "\n" +
"Has Barcode " + HasBarcode + "\n" +
"Card ID: " + CardID + "\n" +
"Store Name: " + StoreName + "\n" +
"Custom Card? " + CustomCard + "\n" +
"Image String: " + Image;
}
}
Изменив тип переменной Image на String, сделал это;
public ArrayList<Card> getCards(MyCardsScreenActivity activity) {
myCards = activity;
String email = SaveSharedPreferences.getUserName(activity);
ArrayList<Card> cards = new ArrayList<>();
try {
String link = "http://address.com/new_get_card_info.php?email=" + email;
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(link));
HttpResponse response = client.execute(request);
String data = EntityUtils.toString(response.getEntity());
Log.d("Pass3?", data.toString());
Gson gson = new Gson();
Card[] cards1 = gson.fromJson(data.toString(), Card[].class);
for(Card card : cards1) {
cards.add(card);
Log.d("Card toString;\n", card.toString());
}
}
catch(Exception ex) {}
if (!cards.isEmpty()) {
myCards.setHasCards(true);
}
else {
myCards.setHasCards(false);
}
return cards;
}
Работа. Тогда я просто должен был справиться с этой строкой;
byte[] bytes = Base64.decode(card.getImageString(), Base64.DEFAULT);
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Опять извините за плохо сформулированный вопрос. Я постараюсь держать свои вопросы ближе к делу в будущем.